
Récupérer des données avec "httpResource()"
Dans l’article précédent, nous avons utilisé la fonction
resource()
mise à disposition depuis Angular 19 afin d’avoir accès à des données asynchrones de façon réactive (et
sans utiliser RxJs).
Depuis Angular 19.2, nous avons également deux outils supplémentaires à disposition (en “developer preview” au moment
de la rédaction de cet article) : httpResource()
et rxResource()
(dont nous ne parlerons pas ici).
httpResource, comment ça fonctionne ?
Alors que resource()
permet de rendre n’importe quelle source de données asynchrone réactive, il est très généraliste
et nécessite de lui passer différentes options ou services.
La plupart du temps sur nos applications, nous avons besoin d’effectuer des requêtes HTTP afin de récupérer les données
nécessaires à son fonctionnement. C’est même souvent la principale (voire l’unique) source de données asynchrones.
Afin de faciliter la déclaration d’une resource()
HTTP, Angular a introduit httpResource()
.
Dans cet article comme le précédent, nous prendrons pour exemple une petite application permettant de charger les
données d’un Pokémon depuis une API (via une requête HTTP). Utilisons httpResource()
plutôt que resource()
pour
la récupération des données :
selectedPokemon = signal(1);
query = httpResource<Pokemon>(
() => `https://tyradex.vercel.app/api/v1/pokemon/${this.selectedPokemon()}`
);
Le code est très simple : httpResource()
prend en paramètre une fonction utilisant un signal, similaire au paramètre
de computed()
, et renvoyant l’URL sur laquelle effectuer la requête. Lorsque le signal change, la requête est
ré-exécutée.
httpResource
utilisera le service HttpClient
comme loader et effectuera par défaut une requête GET. Si le type de
la réponse HTTP n’est pas précisé, cela sera du JSON. L’utilisation d’ HttpClient
permet également l’utilisation
automatique des différents intercepteurs existants.
selectedPokemon = signal(1);
- query = resource({
- request: () => ({ pokedexId: this.selectedPokemon() }),
- loader: ({ request }) =>
- lastValueFrom(
- this.#httpClient.get<Pokemon>(
- `https://tyradex.vercel.app/api/v1/pokemon/${request.pokedexId}`
- )
- ),
+ query = httpResource<Pokemon>(
+ () => `https://tyradex.vercel.app/api/v1/pokemon/${this.selectedPokemon()}`
);
Avoir la main sur la requête HTTP
Si vous avez besoin de plus d’options pour la requête HTTP, vous pouvez également passer un objet en paramètre à
httpResource()
, par exemple :
query = httpResource(() => ({
url: `https://tyradex.vercel.app/api/v1/pokemon/${this.selectedPokemon()}`,
method: 'GET',
headers: {
'X-My-Custom-Header': 'my-value',
},
params: {
'shiny': 'true',
},
reportProgress: true,
withCredentials: true,
transferCache: true,
}));
Avec cette méthode, il est possible d’utiliser une autre méthode HTTP que GET
, cependant les Resource ne sont pas
faites pour modifier les données sur le serveur. Pour la création ou la modification de la ressource sur le serveur,
continuez d’utiliser HttpClient
directement.
Méta-données de la réponse HTTP
En plus des signaux exposés par resource()
(value()
, status()
, isLoading()
et error()
), httpResource
ajoute
les signaux suivants :
headers()
: retourne les “headers” HTTP de la réponse.statusCode()
: retourne le code de retour HTTP.progress()
: retourne la progression de la requête (le nombre de bytes chargés ou téléversés), sireportProgress
est défini àtrue
.
Typage de la valeur et type de la réponse HTTP
Par défaut, httpResource
part du principe que le serveur distant renverra le résultat sous forme d’un JSON. Comme
avec HttpClient
, vous pouvez fournir un type à la fonction pour récupérer un objet de ce type en value()
. Mais
attention, comme avec HttpClient
aucune validation n’est effectuée sur la conformité de la ressource par rapport au
type donné.
// query.value() sera de type "Pokemon"
query = httpResource<Pokemon>(
() => ...
);
Si le type de la réponse HTTP n’est pas du JSON, plusieurs méthodes dédiées sont disponibles sur httpResource
:
httpResource.text( ... ); // retourne du texte dans value()
httpResource.blob( ... ); // retourne un Blob (fichier) dans value()
httpResource.arrayBuffer( ... ); // retourne un ArrayBuffer dans value()
Valider le schéma de la ressource
Et si on souhaite s’assurer que les données retournées respectent un “schéma” spécifique ? Il n’existe pas de service de validation de schéma directement intégré à Angular, néanmoins il existe des modules très utilisés dans l’écosystème JavaScript tel que Zod.
httpResource
met à disposition une façon de valider le schéma des données avec n’importe quel module. Pour cela on
peut passer un second paramètre à httpResource()
, qui est un objet ayant un attribut parse
. Par exemple, avec Zod :
const pokemonSchema = z.object({
name: z.object({
fr: z.string(),
}),
sprites: z.object({
regular: z.string(),
}),
});
type Pokemon = z.infer<typeof pokemonSchema>;
// ...
selectedPokemon = signal(1);
query = httpResource<Pokemon>(
() => `https://tyradex.vercel.app/api/v1/pokemon/${this.selectedPokemon()}`,
{ parse: pokemonSchema.parse }
);
Si la ressource ne respecte pas le schéma indiqué, une erreur sera enregistrée dans query.error()
!
Liens et exemple complet
Vous pouvez retrouver l’exemple complet sur Stackblitz.
Voici également quelques liens vers des sources de documentation :