HTTP Client
Last updated
Last updated
Angular has a built-in http request library.
HttpClient
dependency is provided using the provideHttpClient
helper function in app.config.ts
.
Then you may inject the HttpClient
service as a dependency of the components, services, or other classes.
It is recommended that you create reusable, injectable services which isolate and encapsulate data access logic.
For example, this UserService
encapsulates the logic to request data for a user:
Within the component, you can combine NgIf
and the async
pipe to render the UI for the data only after it's finished loading.
HttpClient
withFetch
By default HttpClient
uses XMLHttpRequest
api to make requests. Use withFetch
feature to switch to fetch
api instead.
It has limitations such as not producing upload progress events.
withInterceptors(...)
Configures the set of interceptor functions which will process requests made through HttpClient
.
Each HttpClient
method for request returns RxJS
Observable
which, when subscribed, sends the request and then emits the results when the server responds.
The request is ONLY sent if you subscribe to the Observable.
Observable
created by HttpClient
may be subscribed any number of times and will make a new request for each subscription.
These subscribtions will be automatically unsubscribed, when the Component is destroyed.
If the data has unknown shape, don't use any
, use unknown
type as the response type.
HttpClient
does not verify if the actual returned data matches the method type asserted.
By default HttpClient
assumes that servers will return JSON data.
You may configure different types with responseType
:
json
: JSON data.
text
: string data.
arraybuffer
: ArrayBuffer
containing raw response bytes.
blob
: A blob instance.
In post
requests many different types of values can be provided as request's body
, an HttpClient
will serialize them accordingly:
string
: As plain text.
number, boolean, array, object
: As JSON data.
ArrayBuffer
: As raw data from the buffer.
Blob
: As raw data with the Blob
's content type.
FormData
: As multipart/form-data
encoded data.
HttpParams
or URLSearchParams
: As application/x-www-form-urlencoded
formatted string.
Specify request parameters that should be included in the request URL.
Specify request headers that should be included in the request.
For convenience HttpClient
only gets the body
from the response.
To access the entire response, set the option observe: 'response'
.
HttpClient
can also return a stream of raw events corresponding to specific moments in the request lifecycle.
These events include when:
The request is sent;
The response header is returned;
The body is complete.
These events can also include progress events which report upload and download status for large request or response bodies.
They are disabled by default as they have performance costs.
The optional fetch
implementation of HttpClient
does not report upload
progress events.
To observe the event stream, set the option observe: 'events'
.
HttpEventType.Sent
The request has been dispatched to the server
HttpEventType.UploadProgress
An HttpUploadProgressEvent
reporting progress on uploading the request body
HttpEventType.ResponseHeader
The head of the response has been received, including status and headers
HttpEventType.DownloadProgress
An HttpDownloadProgressEvent
reporting progress on downloading the response body
HttpEventType.Response
The entire response has been received, including the response body
HttpEventType.User
A custom event from an Http interceptor
HttpClient
will catch errors requests which returns through the Observable
error channel.
There are two ways HTTP requests can fail:
A network or connection error - that prevents the request from reaching the server.
Will have a status
code of 0
.
An error
which is an instance of ProgressEvent
.
The backend receives the request but fails to proccess it, and returns an error response.
Will have a failing status
code returned by the server.
An error
which is the error from the server.
RxJS
offers several operators which can be useful for error handling, like catchError()
.
It also provides several retry
operators for automatically re-subscribing to failed Observables
under certain conditions, like retry()
.
Subject
If multiple parts of the application would want to get the error from the request.
catchError
Useful for handling error behind the scenes, like to send statistics.
Observable
Each request method construct an Observable of the requested response type.
HttpClient
procudes what RxJS calls cold
Observables, meaning that no actual request happens until a subscription takes place.
Each subscription is independent, so multiple subscriptions will trigger multiple requests.
Unsubscribing will abort the in-progress request.
This is very useful if the subscription was done via async
pipes, as it will automatically cancel the request if the user navigates away.
If you use the Observable with the RxJS combinator switchMap
, this cancellation will clean up any stale requests.
It is strongly recommended that you clean up subscriptions when the component using them is destroyed.
rxjs/Operators
HttpClient
supports a form of middleware known as interceptor
.
There are two types:
functional
:
The recommended type to use, since they have more predictable behavior.
DI-based
:
Are interceptors defined as injectable classes and configured through the DI system.
Have the same capabilities as functional
ones.
Interceptors are generally function which you can run for each request.
You can make a chain of interceptors where each interceptor processes the request or response before forwarding it to the next interceptor in the chain.
Adding authentication headers to outgoing requests to a particular API.
Retrying failed requests with exponential backoff.
Caching responses for a period of time, or until invalidated by mutations.
Customizing the parsing of responses.
Measuring server response times and log them.
Driving UI elements such as a loading spinner while network operations are in progress.
Collecting and batch requests made within a certain timeframe.
Automatically failing requests after a configurable deadline or timeout.
Regularly polling the server and refreshing results.
The basic form is a function which receives the outgoing HttpRequest
and a next
function representing the next processing step in the interceptor chain.
You declare the set of interceptors to use through dependency injection, with withInterceptors
.
The interceptors are chained in the order that you've listed them in the providers.
Tap into the next
returned stream in order to manipulate the response.
Most aspects of HttpRequest
and HttpResponse
instances are immutable, and interceptors cannot directly modify them.
Instead, they apply mutations by clonning these objects with .clone()
operation.
The body
of a request or response is NOT protected from deep mutations. If an interceptor must mutate the body, take care to handle running multiple times on the same request.
Interceptors are run in the injection context
of the injector which registered them.
Often it is useful to include information, in a request, that is not sent to the backend, but specifically meant for interceptors.
HttpRequest
have a .context
object which stores this kind of metada.
The .context
is mutable.
If an interceptor changes the context of a request that is later retried, the same interceptor will observe the context mutation when it runs again.
This is useful for passing state across multiple retries if needed.
Define a new HttpContextToken
to act as a key in the .context
.
Interceptors are not required to invoke next
.
They may instead choose to construct responses through some other mechanims, such as from a cache or by sending the request through an alternate mechanims.
You can construct a response with:
A DI-based interceptor is an injectable class which implements the HttpInterceptor
interface.
These interceptors will run in the order that their providers are registered.
So, in apps with extensive and hierarchical DI configuration, this order can be very hard to predict.
They are configured through a dependency injection multi-provider:
For intercepting the Response: