foundation
Services
Keep reusable business logic, HTTP access, state coordination, and side effects in injectable services.
Services are injectable classes (`@Injectable`) holding reusable logic: HTTP clients, facades over stores, coordination between features. They keep components thin and testable.
@Injectable({ providedIn: 'root' })
export class UserApi {
constructor(private http: HttpClient) {}
getUser(id: string) { return this.http.get<User>(`/api/users/${id}`); }
}
`providedIn: 'root'` tree-shakes singletons. Feature-scoped providers create per-lazy-route instances when needed.
On interviews: service versus component state, testing with mocks, and avoiding god-services that know every feature.
Common pitfalls: storing UI view state in root singletons, HttpClient calls without error mapping, and circular service dependencies.
The trade-off is convenient root singletons versus hidden global state that outlives feature boundaries.
Checklist:
- One responsibility per service.
- Root provide for app-wide singletons.
- Feature providers for isolated state.
- Return Observables or Promises consistently.