CodeGym /Blog Java /Random-FR /Présentation de REST. Partie 3 : Création d'un service RE...
John Squirrels
Niveau 41
San Francisco

Présentation de REST. Partie 3 : Création d'un service RESTful sur Spring Boot

Publié dans le groupe Random-FR
Ceci est la dernière partie de notre aperçu de REST. Dans les parties précédentes, nous avons abordé : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 1

Créer un projet

Dans cette section, nous allons créer une petite application RESTful à l'aide de Spring Boot. Notre application implémentera les opérations CRUD (Create, Read, Update, Delete) sur les clients de l'exemple de la partie précédente de l'aperçu. Pour commencer, nous allons créer une nouvelle application Spring Boot via le menu : Fichier -> Nouveau -> Projet... Dans la fenêtre qui s'ouvre, sélectionnez Spring Initializr et spécifiez le SDK du projet : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 2Cliquez sur le bouton "Suivant". Dans la fenêtre suivante, spécifiez "Projet Maven" comme type de projet, spécifiez le "Groupe" et "Artifact": Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 3Cliquez sur le bouton "Suivant". Dans la fenêtre suivante, nous devons sélectionner les composants Spring Framework nécessaires au projet. Spring Web nous suffira : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 4Cliquez sur le bouton "Suivant". Il ne reste plus qu'à indiquer le nom du projet et son emplacement dans le système de fichiers : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 5Cliquez sur le bouton "Terminer". Le projet est créé, et maintenant nous pouvons voir sa structure : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 6IDEA a généré un descripteur de déploiement Maven (pom.xml) et la classe principale de l'application ( RestExampleApplication) pour nous. Voici à quoi ils ressemblent :

pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>
   <parent>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-parent</artifactId>
       <version>2.2.2.RELEASE</version>
       <relativePath/> <!-- lookup parent from repository -->
   </parent>
   <groupId>com.codegym.lessons/groupId>
   <artifactId>rest_example</artifactId>
   <version>0.0.1-SNAPSHOT</version>
   <name>rest_example</name>
   <description>REST example project</description>

   <properties>
       <java.version>1.8</java.version>
   </properties>

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>

       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
           <exclusions>
               <exclusion>
                   <groupId>org.junit.vintage</groupId>
                   <artifactId>junit-vintage-engine</artifactId>
               </exclusion>
           </exclusions>
       </dependency>
   </dependencies>

   <build>
       <plugins>
           <plugin>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-maven-plugin</artifactId>
           </plugin>
       </plugins>
   </build>

</project>
RestExampleApplication :

@SpringBootApplication
public class RestExampleApplication {

   public static void main(String[] args) {
       SpringApplication.run(RestExampleApplication.class, args);
   }

}

Création de la fonctionnalité REST

Notre application est un système de gestion des clients. Donc, la première chose que nous devons faire est de créer une entité client. Ce sera une classe POJO (Plain Old Java Object). Créez un modelpackage à l'intérieur du com.codegym.lessons.rest_examplepackage. Dans le modelpackage, créez leCustomer :

public class Customer {

   private Integer id;
   private String name;
   private String email;
   private String phone;

   public Integer getId() {
       return id;
   }

   public void setId(Integer id) {
       this.id = id;
   }

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public String getEmail() {
       return email;
   }

   public void setEmail(String email) {
       this.email = email;
   }

   public String getPhone() {
       return phone;
   }

   public void setPhone(String phone) {
       this.phone = phone;
   }
}
Le service mettra en œuvre les opérations CRUD sur les clients. L'étape suivante consiste à créer un service qui implémentera ces opérations. Dans le com.codegym.lessons.rest_examplepackage, créez un servicepackage. Et à l'intérieur de cela, créez une CustomerServiceinterface. Voici le code de l'interface avec des commentaires :

public interface CustomerService {

   /**
    * Creates a new customer
    * @param customer - Customer to be created
    */
   void create(Customer customer);

   /**
    * Returns a list of all existing customers
    * @return List of customers
    */
   List<Customer> readAll();

   /**
    * Returns a customer based on its ID
    * @param id - Customer ID
    * @return - Customer object with the given ID
    */
   Customer read(int id);

   /**
    * Updates the customer with the given ID,
    * according to the passed customer
    * @param customer - Customer to use to update the data
    * @param id - ID of the customer you want to update
    * @return - true if the data has been updated, otherwise false
    */
   boolean update(Customer customer, int id);

   /**
    * Deletes the customer with the given ID
    * @param id - ID of the customer to be deleted
    * @return - true if the customer was deleted, otherwise false
    */
   boolean delete(int id);
}
Ensuite, nous devons implémenter cette interface. Maintenant, un magasin Map<Integer, Customer>va stocker nos clients. Les clés de la carte seront les identifiants des clients et les valeurs seront les clients eux-mêmes. Ceci est fait pour ne pas surcharger cet exemple avec les spécificités du travail avec une vraie base de données. Cependant, à l'avenir, nous pourrons écrire une autre implémentation de l'interface, qui permettra de se connecter à une vraie base de données. Dans le servicepackage, créez une implémentation de l' CustomerServiceinterface :

@Service
public class CustomerServiceImpl implements CustomerService {

   // Customer repository
   private static final Map<Integer, Customer> CUSTOMER_REPOSITORY_MAP = new HashMap<>();
  
   // Variable for generating a customer ID
   private static final AtomicInteger CUSTOMER_ID_HOLDER = new AtomicInteger();

   @Override
   public void create(Customer customer) {
       final int customerId = CUSTOMER_ID_HOLDER.incrementAndGet();
       customer.setId(customerId);
       CUSTOMER_REPOSITORY_MAP.put(customerId, customer);
   }

   @Override
   public List<Customer> readAll() {
       return new ArrayList<>(CUSTOMER_REPOSITORY_MAP.values());
   }

   @Override
   public Customer read(int id) {
       return CUSTOMER_REPOSITORY_MAP.get(id);
   }

   @Override
   public boolean update(Customer customer, int id) {
       if (CUSTOMER_REPOSITORY_MAP.containsKey(id)) {
           customer.setId(id);
           CUSTOMER_REPOSITORY_MAP.put(id, customer);
           return true;
       }

       return false;
   }

   @Override
   public boolean delete(int id) {
       return CUSTOMER_REPOSITORY_MAP.remove(id) != null;
   }
}
L' @Serviceannotation indique à Spring que cette classe est un service. Il s'agit d'un type spécial de classe qui implémente une logique d'application métier. Par la suite, grâce à cette annotation, Spring utilisera l'injection de dépendances pour nous fournir une instance de cette classe à tous les endroits où elle est nécessaire. Il est maintenant temps de créer un contrôleur. Il s'agit d'une classe spéciale dans laquelle nous allons implémenter la logique de traitement des requêtes client envoyées aux points de terminaison (URI). Pour rendre tout cela plus clair, nous allons créer cette classe progressivement. Tout d'abord, créez la classe elle-même et ajoutez une dépendance surCustomerService :

@RestController
public class CustomerController {

   private final CustomerService customerService;

   @Autowired
   public CustomerController(CustomerService customerService) {
       this.customerService = customerService;
   }
}
Expliquons les annotations : @RestController indique à Spring que cette classe est un contrôleur REST. En d'autres termes, cette classe implémente la logique de traitement des requêtes client. @Autowired indique à Spring qu'une dépendance doit être ajoutée ici. Nous passons l' CustomerServiceinterface au constructeur. Plus tôt, nous avons marqué l'implémentation de ce service avec l' @Serviceannotation, et maintenant Spring pourra transmettre une instance de cette implémentation au constructeur du contrôleur. Ensuite, nous allons implémenter chaque méthode de contrôleur pour gérer les opérations CRUD. Commençons par l'opération de création. Pour cela, écrivons une createméthode :

@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
   customerService.create(customer);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Analysons cette méthode : @PostMapping(value = "/customers")signifie que cette méthode traite les requêtes POST envoyées à l'adresse "/customers". La méthode retourne un ResponseEntity<?>. A ResponseEntityest une classe spéciale pour renvoyer des réponses. Plus tard, nous l'utiliserons pour renvoyer un code d'état HTTP au client. La méthode a un @RequestBody Customer customerparamètre. La valeur de ce paramètre provient du corps de la requête. L' @RequestBodyannotation l'indique. Dans le corps de la méthode, nous appelons la create()méthode sur le service créé précédemment et la transmettons au contrôleur client reçu dans les paramètres. Ensuite, nous renvoyons le statut "201 Created" en créant un nouvel ResponseEntityobjet et HttpStatusen lui passant le champ enum correspondant. Ensuite, nous allons implémenter lereadopération : Tout d'abord, nous allons implémenter l'opération pour obtenir une liste de tous les clients disponibles :

@GetMapping(value = "/customers")
public ResponseEntity<List<Customer>> read() {
   final List<Customer> customers = customerService.readAll();

   return customers != null &&  !customers.isEmpty()
           ? new ResponseEntity<>(customers, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Plongeons-nous : @GetMapping(value = "/customers")- tout ici est similaire à l' @PostMappingannotation, mais nous traitons maintenant les requêtes GET. Cette fois, nous renvoyons un ResponseEntity<List<Customer>>, et en plus d'un statut HTTP, nous renverrons également un corps de réponse, qui sera la liste des clients. Dans les contrôleurs REST de Spring, tout est constitué d'objets POJO et de collections d'objets POJO, qui sont renvoyés sous forme de corps de réponse et automatiquement sérialisés en JSON, sauf indication contraire. Cela nous convient parfaitement. À l'intérieur de la méthode, nous utilisons notre service pour obtenir une liste de tous les clients. Ensuite, si la liste n'est ni nulle ni vide, alors nous utilisons leResponseEntityclass pour renvoyer la liste des clients et le code de statut HTTP "200 OK". Sinon, nous renvoyons simplement le code d'état HTTP "404 Not Found". Nous allons maintenant implémenter la possibilité d'obtenir un client en utilisant son ID :

@GetMapping(value = "/customers/{id}")
public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
   final Customer customer = customerService.read(id);

   return customer != null
           ? new ResponseEntity<>(customer, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Une nouveauté ici est la variable de chemin. La variable est définie dans l'URI : value = "/customers/{id}". Nous l'indiquons entre accolades. Et nous le recevons comme intparamètre de méthode en utilisant l' @PathVariable(name = "id")annotation. Cette méthode accepte les requêtes envoyées aux URI sous la forme /customers/{id}, où {id}représente n'importe quelle valeur numérique. Cette valeur est ensuite transmise via la int idvariable au paramètre de méthode. Dans le corps, nous obtenons l' Customerobjet en utilisant notre service et le reçu id. Et puis, par analogie avec la liste, on retourne soit le statut "200 OK" et l' Customerobjet lui-même, soit simplement le statut "404 Not Found" si le système n'a pas de client avec ça id. Nous devons encore implémenter deux opérations : mettre à jour et supprimer. Voici le code de ces méthodes :

@PutMapping(value = "/customers/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
   final boolean updated = customerService.update(customer, id);

   return updated
           ? new ResponseEntity<>(HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}

@DeleteMapping(value = "/customers/{id}")
public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
   final boolean deleted = customerService.delete(id);

   return deleted
           ? new ResponseEntity<>(HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
Il n'y a rien d'essentiellement nouveau dans ces méthodes, nous allons donc ignorer la description détaillée. La seule chose qui mérite d'être mentionnée est que la update()méthode gère les requêtes PUT ( @PutMappingannotation) et que la delete()méthode gère les requêtes DELETE ( DeleteMappingannotation). Voici le code complet du contrôleur :

@RestController
public class CustomerController {

   private final CustomerService customerService;

   @Autowired
   public CustomerController(CustomerService customerService) {
       this.customerService = customerService;
   }

   @PostMapping(value = "/customers")
   public ResponseEntity<?> create(@RequestBody Customer customer) {
       customerService.create(customer);
       return new ResponseEntity<>(HttpStatus.CREATED);
   }

   @GetMapping(value = "/customers")
   public ResponseEntity<List<Customer>> read() {
       final List<Customer> customers = customerService.readAll();

       return customers != null &&  !customers.isEmpty()
               ? new ResponseEntity<>(customers, HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_FOUND);
   }

   @GetMapping(value = "/customers/{id}")
   public ResponseEntity<Customer> read(@PathVariable(name = "id") int id) {
       final Customer customer = customerService.read(id);

       return customer != null
               ? new ResponseEntity<>(customer, HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_FOUND);
   }

   @PutMapping(value = "/customers/{id}")
   public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Customer customer) {
       final boolean updated = customerService.update(customer, id);

       return updated
               ? new ResponseEntity<>(HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
   }

   @DeleteMapping(value = "/customers/{id}")
   public ResponseEntity<?> delete(@PathVariable(name = "id") int id) {
       final boolean deleted = customerService.delete(id);

       return deleted
               ? new ResponseEntity<>(HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
   }
}
En conséquence, la structure de notre projet est la suivante : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 7

Lancement et test

Pour démarrer notre application, il suffit d'exécuter la main()méthode dans la RestExampleApplicationclasse. Mais pour tester les services Web RESTful, nous devons télécharger un logiciel supplémentaire. Le fait est que les requêtes GET sont assez simples à envoyer à partir d'un navigateur ordinaire, mais un navigateur ordinaire ne peut pas envoyer de requêtes POST, PUT et DELETE. Ne vous inquiétez pas : vous pouvez utiliser un programme appelé Postman pour envoyer des requêtes HTTP. Vous pouvez le télécharger ici . Après avoir téléchargé et installé Postman, nous commençons à tester notre application. Pour cela, ouvrez le programme et créez une nouvelle demande : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 9Cliquez sur le bouton "Nouveau" dans le coin supérieur gauche. Ensuite, sélectionnez "Request": Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 10Ensuite, donnez-lui un nom et enregistrez-le. Essayons maintenant d'envoyer une requête POST au serveur et de créer le premier client : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 11Nous créons ainsi plusieurs clients. Ensuite, nous changeons le type de requête en GET et envoyons la requête au serveur : Présentation de REST.  Partie 3 : Créer un service RESTful sur Spring Boot - 12

Résumé

Toutes nos félicitations! Nous avons suffisamment couvert REST. Il y avait un grand volume de matériel, mais j'espère qu'il vous a été utile :
  1. Nous avons appris ce qu'est REST.

  2. Nous avons appris comment REST a vu le jour.

  3. Nous avons parlé des limites et des principes de ce style architectural :

    • architecture client-serveur
    • apatride
    • mise en cache
    • interface uniforme
    • couches
    • code sur demande (optionnel)
  4. Nous avons exploré les avantages offerts par REST

  5. Nous avons examiné en détail comment le serveur et le client interagissent via le protocole HTTP.

  6. Nous avons examiné de plus près les demandes et les réponses. Nous avons disséqué leurs parties constituantes.

  7. Enfin, nous avons acquis une expérience pratique en écrivant notre propre petite application RESTful à l'aide de Spring Boot. Et nous avons même appris à le tester avec Postman.

Phew. C'était beaucoup, mais il vous reste encore quelque chose à faire comme devoir.

Devoirs

Essayez ce qui suit :
  1. En suivant la description ci-dessus, créez votre propre projet Spring Boot et implémentez la même logique que dans la leçon. Répétez tout exactement.
  2. Lancez l'application.
  3. Téléchargez et configurez Postman (ou tout autre outil pour envoyer des requêtes, par exemple curl).
  4. Testez les requêtes POST et GET de la même manière que celle décrite dans la leçon.
  5. Testez vous-même les requêtes PUT et DELETE.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION