skills/dev-skills/angular-developer/references/http-client.md
HttpClient and httpResourceUse Angular's HTTP APIs for backend communication so requests participate in dependency injection, interceptors, transfer cache, and security features.
In Angular v21 and later, HttpClient is available for injection by default. Add provideHttpClient(...) only when an app needs to configure HTTP features for a specific injector:
import {provideHttpClient, withInterceptors} from '@angular/common/http';
export const appConfig = {
providers: [provideHttpClient(withInterceptors([authInterceptor]))],
};
HttpClient uses the fetch backend by default.withXhr() only when upload progress events are required. Do not use withXhr() for server-side rendering.provideHttpClient(...) for feature configuration such as interceptors, XSRF options, XHR, or parent-request delegation.provideHttpClient() with no features is not required for basic HTTP requests, but it configures the default HTTP feature set for that injector, including Angular's XSRF interceptor.provideHttpClient(...) over HttpClientModule for feature configuration, especially with multiple injectors.withRequestsMadeViaParent() when a child injector should add interceptors while still delegating to the parent HTTP chain.HttpClientEncapsulate backend calls in injectable services, not components:
import {HttpClient} from '@angular/common/http';
import {Service, inject} from '@angular/core';
@Service()
export class UserService {
private readonly http = inject(HttpClient);
getUser(id: string) {
return this.http.get<User>(`/api/users/${id}`);
}
}
Important rules:
HttpClient requests are cold Observables. No request is sent until the Observable is subscribed to. Multiple subscriptions send multiple backend requests.post, put, patch, delete) so they execute.responseType and observe; if options are extracted, write values like responseType: 'text' as const.HttpHeaders and HttpParams are immutable; use the returned instance from .set() or .append().timeout, cache, priority, mode, redirect, credentials, keepalive, referrer, referrerPolicy, and integrity are supported where the backend supports them. withCredentials: true overrides credentials.HttpErrorResponse. Network and timeout failures use status 0; backend failures use the server status code.async pipe or toSignal for component reads so subscriptions are cleaned up.Prefer functional interceptors configured with withInterceptors.
import {
HttpHandlerFn,
HttpRequest,
provideHttpClient,
withInterceptors,
} from '@angular/common/http';
export function authInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn) {
return next(req.clone({setHeaders: {Authorization: 'Bearer token'}}));
}
export const appConfig = {
providers: [provideHttpClient(withInterceptors([authInterceptor]))],
};
inject() inside functional interceptors for services.HttpContextToken for per-request metadata that interceptors need but the backend should not receive.withInterceptorsFromDi().HttpClient strips the XSSI prefix from JSON responses when present.provideHttpClient() configures XSRF protection by default for mutating relative and same-origin requests. It reads the XSRF-TOKEN cookie and sends the X-XSRF-TOKEN header.withXsrfConfiguration(...); disable only deliberately with withNoXsrfProtection().httpResourceUse httpResource to create an asynchronous derivation that fetches data over HTTP and exposes the result as reactive signals.
import {httpResource} from '@angular/common/http';
import {input} from '@angular/core';
export class UserProfile {
readonly userId = input.required<string>();
readonly user = httpResource(() => `/api/users/${this.userId()}`);
}
httpResource is eager. It sends a request when its reactive request computation runs, not when an Observable is subscribed.undefined from the request function to skip a backend request.httpResource for reads. Use HttpClient directly for mutations such as POST, PUT, PATCH, and DELETE.value() reads with hasValue(); reading value() while the resource is in an error state throws.httpResource.text, httpResource.blob, or httpResource.arrayBuffer for non-JSON responses.parse option to validate or transform responses with a runtime schema.headers(), statusCode(), and progress() when response metadata or download progress is needed. Set reportProgress: true for progress events.