0 day streak
javascript / intermediate
Snippet

Encapsulating Repository Operations with Abstract Generic Base Services

Object-Oriented Programming (OOP) inheritance allows sharing core data access logic across services while enforcing strict type contracts. By defining an abstract base class bounded by a generic entity interface, derived services only need to specify their unique endpoint, inheriting fully typed HTTP retrieval and deletion methods without redundant boilerplate.

snippet.js
javascript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import { HttpClient } from '@angular/common/http';
import { inject } from '@angular/core';
import { Observable } from 'rxjs';
export interface IdentifiableEntity {
id: string | number;
}
export abstract class AbstractEntityService<T extends IdentifiableEntity> {
protected readonly http = inject(HttpClient);
protected abstract readonly endpoint: string;
public getById(id: T['id']): Observable<T> {
return this.http.get<T>(`${this.endpoint}/${id}`);
}
public deleteById(id: T['id']): Observable<void> {
return this.http.delete<void>(`${this.endpoint}/${id}`);
}
}
angular
Breakdown
1
export abstract class AbstractEntityService<T extends IdentifiableEntity> {
Declares an abstract base service parameterized with a generic type extending IdentifiableEntity.
2
protected abstract readonly endpoint: string;
Forces all inheriting concrete services to define their specific API base URL endpoint.
3
public getById(id: T['id']): Observable<T> {
Uses indexed access types (T['id']) to guarantee the parameter type strictly matches the entity's identifier type.
4
return this.http.get<T>(`${this.endpoint}/${id}`);
Executes the typed HTTP GET call against the combined base endpoint and entity identifier.