Chapitre API RESTful avec Quarkus
Les annotations JAX-RS
Le but de cet exercice est d'approfondir les connaissances en matière de développement d'API RESTful avec Quarkus.
Notamment nous allons passer en revue les annotations JAX-RS les plus utiles.
Prérequis
Avant de commencer cet exercice, assurez-vous d'avoir les éléments suivants installés sur votre système :
- JDK 11 ou supérieur
- Apache Maven
- Un éditeur de texte ou une IDE Java (comme Eclipse, IntelliJ IDEA, ou Visual Studio Code)
Les annotations JAX RS
Les annotations JAX-RS sont utilisées pour développer des services web RESTful en Java. Voici quelques-unes des annotations les plus importantes à connaître :
@Path
: Cette annotation est utilisée pour spécifier le chemin d'accès relatif d'une ressource ou d'une méthode d'une classe de ressource.@GET, POST, @PUT, @DELETE, @PATCH
: Ces annotations sont utilisées pour spécifier le type de méthode HTTP (GET, POST, PUT, DELETE, PATCH) qui sera associé à la méthode annotée.@Produces
: Utilisé pour spécifier le type de média (comme JSON, XML) produit par la méthode annotée@Consumes
: Utilisé pour spécifier le type de média (comme JSON, XML) consommé par la méthode annotée.@PathParam
: Permet de lier une variable de chemin à un paramètre de méthode.@QueryParam
: Utilisé pour lier une variable de requête à un paramètre de méthode.@HeaderParam
: Utilisé pour lier une variable d'en-tête HTTP à un paramètre de méthode.@FormParam
: Utilisé pour lier un paramètre de formulaire HTML à un paramètre de méthode.@Context
: Permet d'injecter des contextes spécifiques (comme l'URIInfo, HttpHeaders, etc.) dans une méthode.@DefaultValue
: Utilisé pour spécifier une valeur par défaut pour les paramètres de requête ou de chemin.
Ces annotations sont essentielles pour le développement d'applications web RESTful en utilisant JAX-RS, et leur bonne utilisation permet de créer des services web bien structurés et faciles à utiliser.
Comment utiliser les annotations ?
Nous pouvons ajouter de nouveauxy endpoints REST au projet monster-adoption-store-backend
, en utilisant les annotations JAX-RS.
Nous allons ainsi modifier la classe AdoptionResource.java
.
Voici la classe dans son état après les précédents exercises :
package com.byoskill.adoption.controllers;
import com.byoskill.adoption.model.Monster;
import com.byoskill.adoption.repository.AdoptionRepository;
import io.smallrye.mutiny.Uni;
import jakarta.inject.Inject;
import jakarta.ws.rs.DELETE;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.POST;
import jakarta.ws.rs.PUT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.core.MediaType;
import org.jboss.resteasy.reactive.ResponseStatus;
@Path("/adoptions")
@Produces(MediaType.APPLICATION_JSON)
public class AdoptionResource {
@Inject
AdoptionRepository adoptionRepository;
@GET
public Uni<MonsterView> getAllMonsters() {
return adoptionRepository.getAllMonsters()
.log("getAllMonsters")
.collect()
.asList()
.map(MonsterView::new);
}
@GET
@Path("/{id}")
public Uni<Monster> getMonsterByUuid(String id) {
return adoptionRepository.getMonsterByUuid(id);
}
@GET
@Path("/search/{name}")
public Uni<MonsterView> searchMonstersByName(String name) {
return adoptionRepository.searchMonstersByName(name).collect().asList().map(MonsterView::new);
}
@POST
public Uni<Monster> createMonster(Monster monster) {
return adoptionRepository.addMonsterToAdopt(monster);
}
@DELETE
@Path("/{id}")
@ResponseStatus(204)
public void deleteMonsterById(String id) {
adoptionRepository.deleteMonsterById(id);
}
@PUT
@Path("/{id}")
public Uni<Monster> updateMonsterById(String id, Monster monster) {
return adoptionRepository.updateMonsterByUUID(id, monster);
}
}
Utilisation de l'annotation Path
Dans cet exemple, l'annotation @Path est utilisée pour définir un sous-chemin dans le chemin /adoptions. Cela vous permet de regrouper des points de terminaison associés et de créer une API plus organisée et RESTful.
La méthode getAvailableMonsters retourne une liste de tous les monstres disponibles pour adoption. Ce point de terminaison pourrait être utile pour une application cliente qui souhaite afficher une liste de monstres adoptables aux utilisateurs.
@GET
@Path("/adoptions/available")
public Uni<MonsterView> getAvailableMonsters() {
return adoptionRepository.getAllMonsters()
.log("getAvailableMonsters")
.collect()
.asList()
.map(MonsterView::new);
}
Utilisation de l'annotation Produces
Voici un autre exemple de point de terminaison REST qui démontre les possibilités de l'annotation @Produces:
@GET
@Path("/monsters")
@Produces(MediaType.APPLICATION_JSON)
public Uni<List<Monster>> getAllMonsters() {
return adoptionRepository.getAllMonsters();
}
Dans cet exemple, l'annotation @Produces est utilisée pour spécifier que la méthode getAllMonsters produira une réponse au format JSON. Ceci est utile pour les clients qui s'attendent à recevoir des données JSON de l'API.
Vous pouvez également utiliser l'annotation @Produces pour spécifier plusieurs types de média que la méthode peut produire. Par exemple, la méthode suivante peut produire des données JSON ou XML:
@GET
@Path("/monsters")
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Uni<List<Monster>> getAllMonsters() {
return adoptionRepository.getAllMonsters();
}
Le client peut spécifier le type de support qu'il souhaite recevoir en définissant l'en-tête Accept dans la demande.
Dans cet exemple, l'annotation @Produces est utilisée pour spécifier que la méthode getAllMonsters produira une réponse au format JSON. Ceci est utile pour les clients qui s'attendent à recevoir des données JSON de l'API.
Vous pouvez également utiliser l'annotation @Produces pour spécifier plusieurs types de média que la méthode peut produire. Par exemple, la méthode suivante peut produire des données JSON ou XML:
@GET
@Path("/monsters")
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Uni<MonsterView> getAllMonsters2() {
return adoptionRepository.getAllMonsters()
.log("getAllMonsters")
.collect()
.asList()
.map(MonsterView::new);
}
Utilisation de l'annotation Consumes
Voici un autre exemple de point de terminaison REST qui démontre les possibilités de l'annotation @ Consumes:
@POST
@Path("/monsters")
@Consumes(MediaType.APPLICATION_JSON)
public Uni<Monster> createMonster(Monster monster) {
return adoptionRepository.addMonsterToAdopt(monster);
}
Dans cet exemple, l'annotation @Consumes est utilisée pour spécifier que la méthode createMonster consommera un corps de requête au format JSON. Ceci est utile pour les clients qui souhaitent envoyer des données JSON à l'API.
Vous pouvez également utiliser l'annotation @Consumes pour spécifier plusieurs types de média que la méthode peut consommer. Par exemple, la méthode suivante peut consommer des données JSON ou XML:
@POST
@Path("/monsters")
@Consumes({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public Uni<Monster> createMonster(Monster monster) {
return adoptionRepository.addMonsterToAdopt(monster);
}
Le client peut spécifier le type de média qu'il souhaite envoyer en définissant l'en-tête Content-Type
dans la requête.