A
Arthur Groupp
Guest

Data fetching has always been a tricky balancing act in Angular:
Where should the logic live β inside the component or abstracted elsewhere?
With the introduction of
httpResource
in Angular 19, this question is more relevant than ever. httpResource
provides a reactive, signal-driven way to work with HTTP calls β but if misused, it can quickly tangle business logic with UI code.In this article, weβll explore what
httpResource
does, the temptation of in-component usage, and why service-based abstraction is the key to maintainable, scalable applications.Why httpResource
Matters
At its core,
httpResource
is a reactive wrapper around Angularβs HttpClient
.Instead of manually subscribing to Observables,
httpResource
integrates seamlessly with the signals ecosystem β meaning its results can be consumed by computed
, effect
, linkedSignal
, or directly in templates.Some key properties:
- Eager execution: Unlike
HttpClient
, which only fires on subscription,httpResource
eagerly triggers requests when its reactive dependencies change. - Automatic cancellation: If dependencies change mid-request, the in-flight request is canceled and a new one is issued.
- Full
HttpClient
support: Interceptors and all other features still apply.
Example of a simple reactive resource:
Code:
userId = input<string>();
user = httpResource(() => `/api/user/${userId()}`);
Whenever
userId
changes, a fresh request is dispatched automatically.The Temptation: Quick In-Component Usage
The most straightforward way to use
httpResource
is directly in a component:
Code:
@Component({ /* ... */ })
export class MyUserComponent {
userId = input<string>();
userResource = httpResource(() => `/api/user/${this.userId()}`);
}
It works β but this convenience comes at a cost.
By mixing data-fetching logic into the component:
- You violate single responsibility β components should focus on rendering and interaction, not on orchestrating HTTP calls.
- Business logic becomes scattered and harder to reuse.
- Testing gets messy: mocking component state and HTTP behavior together is more complex.
For tiny apps or prototypes, this pattern might be acceptable. However, in real-world applications, it creates tight coupling and long-term maintenance headaches.
The Better Way: Abstract httpResource
into Services
A cleaner approach is to define
httpResource
inside dedicated services, not components.This service-based pattern offers several advantages:
- Separation of concerns: Components stay UI-focused while services handle data logic.
- Reusability: Multiple components can consume the same resource logic.
- Simpler testing: Service logic can be tested independently of UI behavior.
- Consistency: Teams can share and maintain standardized resource definitions.
Example: Service-Based Resource
Code:
// user.service.ts
@Injectable()
export class UserService {
// A shared resource for all consumers
readonly usersResource = httpResource(() => `/api/users`);
// Factory method for reactive user fetching
createUserResource($userId: Signal<string>) {
return httpResource(() => (
$userId() ? `/api/user/${$userId()}` : undefined
));
}
}
// user-details.component.ts
@Component({ /* ... */ })
export class UserDetailsComponent {
readonly userId = input<string>();
readonly #userService = inject(UserService);
readonly userResource = this.#userService.createUserResource(this.userId);
}
When Might In-Component Be Okay?
To keep this balanced:
- Demos, prototypes, or playgrounds β quick feedback matters more than clean architecture.
- Truly one-off fetches β where introducing a service would be unnecessary overhead.
But beyond these cases, service abstraction almost always pays off.
Conclusion: Future-Proof Your Angular Apps
Angularβs
httpResource
is a big step forward for reactive data fetching. But its power can become a liability if used naively inside components.By moving your resource definitions into services, you get:
- Cleaner components
- Reusable data logic
- Easier testing and scaling

httpResource
, ask: βShould this live in a component β or does it belong in a service?βChances are, the service wins.
This simple shift will prepare your codebase for growth, teamwork, and the evolving Angular ecosystem.
Continue reading...