--- name: angular-architecture-facade-pattern description: "Introduces or reviews Angular facades that provide a focused feature API over data access, state, permissions, navigation, and orchestration." license: MIT metadata: ngautopilot-id: "angular.architecture.facade-pattern" ngautopilot-source: "skills/angular/architecture/facade-pattern/SKILL.md" ngautopilot-version: "0.6.0" --- # Angular Facade Pattern ## Purpose Use this skill to introduce a focused feature API between components and lower-level services. The goal is to reduce coupling, simplify tests, and keep orchestration out of UI components. ## When to Use Use this skill when: - A component injects many services from different concerns. - Components duplicate loading, error, permission, and mapping logic. - Tests require excessive mocks for one feature component. - Several components need the same feature-level operations. - Feature state and API calls need a stable public contract. - A module, route, or microfrontend boundary needs an explicit interface. ## Do Expose a narrow feature contract: ```ts @Injectable() export class UserFacade { readonly users$ = this.userState.users$; readonly loading$ = this.userState.loading$; readonly error$ = this.userState.error$; constructor( private readonly userApi: UserApiService, private readonly userState: UserStateService, ) {} loadUsers(): void { this.userState.setLoading(true); this.userApi .getUsers() .pipe(finalize(() => this.userState.setLoading(false))) .subscribe({ next: (users) => this.userState.setUsers(users), error: (error) => this.userState.setError(error), }); } } ``` Keep the component simple: ```ts readonly users$ = this.userFacade.users$; readonly loading$ = this.userFacade.loading$; ngOnInit(): void { this.userFacade.loadUsers(); } ``` Use a structure that reveals boundaries: ```txt users/ data-access/ user-api.service.ts user-state.service.ts facade/ user.facade.ts feature/ users-page.component.ts ui/ user-list.component.ts models/ user.model.ts ``` ## Do Not Avoid a facade that becomes a god service: ```txt UserFacade - users - auth - payments - notifications - export - analytics ``` Avoid adding a facade for a trivial component if it only forwards one method and adds no stable boundary. Avoid hiding bad domain boundaries behind a nicer class name. Avoid mixing UI formatting, API calls, permissions, and unrelated business domains in the same facade. ## Review Checklist - [ ] The facade owns one feature or bounded context. - [ ] Components depend on the facade instead of many low-level services. - [ ] Public facade properties are readonly. - [ ] Commands are named by user or feature intent. - [ ] Data access and state services remain separate when complexity justifies it. - [ ] The facade simplifies tests with fewer mocks. - [ ] The facade does not become a dumping ground. - [ ] Signals are only exposed when the Angular version and project style support them. ## Expected Output When this skill is used, the agent should: 1. Identify coupling between components and low-level services. 2. Decide whether a facade creates real value. 3. Propose a bounded facade API. 4. Move orchestration behind the facade incrementally. 5. Provide testing guidance using facade mocks.