JavaRush /Blog Java /Random-FR /Présentation de REST. Partie 3 : Création d'un service RE...

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

Publié dans le groupe Random-FR
C'est la dernière partie de l'analyse REST. Dans les parties précédentes : Présentation de REST.  Partie 3 : Création d'un service RESTful dans 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 à partir de l'exemple de la dernière partie de l'analyse. Tout d'abord, créons 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 Project SDK : Présentation de REST.  Partie 3 : Création d'un service RESTful dans Spring Boot - 2cliquez sur le bouton Suivant. Dans la fenêtre suivante, spécifiez le type de projet Maven, spécifiez Group et Artefact : Présentation de REST.  Partie 3 : Création d'un service RESTful dans 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éation d'un service RESTful dans Spring Boot - 4cliquez sur le bouton Suivant. Il ne reste ensuite plus qu'à préciser le nom du projet et son emplacement dans le système de fichiers : Présentation de REST.  Partie 3 : Création d'un service RESTful dans Spring Boot - 5Cliquez sur le bouton Terminer. Le projet a été créé, nous pouvons maintenant voir sa structure : Présentation de REST.  Partie 3 : Création d'un service RESTful dans Spring Boot - 6IDEA a généré pour nous le descripteur de déploiement du système de build Maven - pom.xml et la classe d'application principale : RestExampleApplication. Voici leur code :
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.javarush.lectures</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 fonctionnalités REST

Notre application gère les clients. La première chose que nous devons faire est donc de créer une entité client. Ce sera un cours POJO. Créons un paquet modelà l'intérieur d'un paquet com.javarush.lectures.rest_example. modelCréons une classe à l'intérieur du packageClient :
public class Client {

   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 implémentera les opérations CRUD sur le client. L'étape suivante consiste à créer un service qui mettra en œuvre ces opérations. Dans le package , com.javarush.lectures.rest_examplenous créerons un package serviceà l'intérieur duquel nous créerons une interface ClientService. Voici le code de l'interface avec commentaires :
public interface ClientService {

   /**
    * Создает нового клиента
    * @param client - клиент для создания
    */
   void create(Client client);

   /**
    * returns список всех имеющихся клиентов
    * @return список клиентов
    */
   List<client> readAll();

   /**
    * returns клиента по его ID
    * @param id - ID клиента
    * @return - an object клиента с заданным ID
    */
   Client read(int id);

   /**
    * Обновляет клиента с заданным ID,
    * в соответствии с переданным клиентом
    * @param client - клиент в соответсвии с которым нужно обновить данные
    * @param id - id клиента которого нужно обновить
    * @return - true если данные были обновлены, иначе false
    */
   boolean update(Client client, int id);

   /**
    * Удаляет клиента с заданным ID
    * @param id - id клиента, которого нужно удалить
    * @return - true если клиент был удален, иначе false
    */
   boolean delete(int id);
}
Ensuite, nous devons créer une implémentation de cette interface. Il fera désormais office de référentiel client Map<Integer, Client>. La clé de la carte sera l'identifiant du client et la valeur sera le client lui-même. Cela a été fait afin de ne pas surcharger l'exemple avec les spécificités du travail avec la base de données. Cependant, à l'avenir, nous pourrons écrire une autre implémentation de l'interface dans laquelle il sera possible de connecter une vraie base de données. Dans le package servicenous allons créer une implémentation de l'interface ClientService:
@Service
public class ClientServiceImpl implements ClientService {

   // Хранorще клиентов
   private static final Map<Integer, Client> CLIENT_REPOSITORY_MAP = new HashMap<>();

   // Переменная для генерации ID клиента
   private static final AtomicInteger CLIENT_ID_HOLDER = new AtomicInteger();

   @Override
   public void create(Client client) {
       final int clientId = CLIENT_ID_HOLDER.incrementAndGet();
       client.setId(clientId);
       CLIENT_REPOSITORY_MAP.put(clientId, client);
   }

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

   @Override
   public Client read(int id) {
       return CLIENT_REPOSITORY_MAP.get(id);
   }

   @Override
   public boolean update(Client client, int id) {
       if (CLIENT_REPOSITORY_MAP.containsKey(id)) {
           client.setId(id);
           CLIENT_REPOSITORY_MAP.put(id, client);
           return true;
       }

       return false;
   }

   @Override
   public boolean delete(int id) {
       return CLIENT_REPOSITORY_MAP.remove(id) != null;
   }
}
L'annotation @Serviceindique à Spring que cette classe est un service. Il s'agit d'un type spécial de classe dans laquelle une certaine logique métier de l'application est implémentée. Par la suite, grâce à cette annotation, Spring nous fournira une instance de cette classe aux endroits où elle est nécessaire grâce à l'injection de dépendances. Il est maintenant temps de créer le contrôleur. Une classe spéciale dans laquelle nous implémentons la logique de traitement des demandes des clients pour les points de terminaison (URI). Pour que ce soit plus clair, nous allons créer cette classe en plusieurs parties. Tout d'abord, créons la classe elle-même et introduisons une dépendance dessusClientService :
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }
}
Clarifions les annotations : @RestController - indique à Spring que cette classe est un contrôleur REST. Ceux. cette classe implémentera la logique de traitement des requêtes des clients. @Autowired - indique à Spring qu'une dépendance doit être injectée à cet endroit. Nous passons l'interface au constructeur ClientService. Nous avons marqué l'implémentation de ce service avec une annotation @Serviceplus tôt, et Spring pourra désormais transmettre une instance de cette implémentation au constructeur du contrôleur. Ensuite, nous implémenterons étape par étape chaque méthode de contrôleur pour traiter les opérations CRUD. Commençons par l'opération Créer. Pour ce faire, écrivons une méthode create:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
   clientService.create(client);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Regardons cette méthode : @PostMapping(value = "/clients")- nous entendons ici que cette méthode traite les requêtes POST à ​​l'adresse /clients. La méthode renvoie ResponseEntity<?>. ResponseEntity- une classe spéciale pour renvoyer les réponses. En l'utilisant, nous pouvons ensuite renvoyer le code d'état HTTP au client. La méthode prend un paramètre @RequestBody Client client, la valeur de ce paramètre est remplacée par le corps de la requête. Le résumé en parle @RequestBody. A l'intérieur du corps de la méthode, on appelle la méthode create sur le service créé précédemment et on lui passe le contrôleur client accepté dans les paramètres. Ensuite, nous renvoyons le statut 201 Created en créant un nouvel objet ResponseEntityet en lui transmettant la valeur enum requise HttpStatus. Ensuite, nous mettons en œuvre l'opération Read: Tout d'abord, nous mettons en œuvre l'opération d'obtention d'une liste de tous les clients disponibles :
@GetMapping(value = "/clients")
public ResponseEntity<List<Client>> read() {
   final List<Client> clients = clientService.readAll();

   return clients != null &&  !clients.isEmpty()
           ? new ResponseEntity<>(clients, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Commençons l'analyse : @GetMapping(value = "/clients")- tout est similaire à l'annotation @PostMapping, seulement maintenant nous traitons les requêtes GET. Cette fois, nous revenons ResponseEntity<List<Client>>, mais cette fois, en plus du statut HTTP, nous renverrons également le corps de la réponse, qui sera une liste de clients. Dans les contrôleurs Spring REST, tous les objets POJO, ainsi que les collections d'objets POJO renvoyés en tant que corps de réponse, sont automatiquement sérialisés en JSON, sauf indication contraire explicite. Cela nous convient plutôt bien. Dans la méthode, en utilisant notre service, nous obtenons une liste de tous les clients. Ensuite, si la liste n'est pas nulle ou vide, nous renvoyons ResponseEntityla liste des clients et le statut HTTP 200 OK en utilisant la classe. Sinon, nous renvoyons simplement le statut HTTP 404 Not Found. Ensuite, nous allons implémenter la possibilité de recevoir un client par son identifiant :
@GetMapping(value = "/clients/{id}")
public ResponseEntity<Client> read(@PathVariable(name = "id") int id) {
   final Client client = clientService.read(id);

   return client != null
           ? new ResponseEntity<>(client, HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
Ce qui est nouveau, c'est que nous disposons désormais d'une variable de chemin. Variable définie dans un URI. value = "/clients/{id}". Nous l'avons indiqué entre accolades. Et dans les paramètres de la méthode, nous l'acceptons comme intvariable en utilisant l'annotation @PathVariable(name = "id"). Cette méthode acceptera les demandes d'uri du formulaire /clients/{id}, où à la place {id}il peut y avoir n'importe quelle valeur numérique. Cette valeur est ensuite transmise à une variable int id: le paramètre de méthode. Dans le corps, nous recevons l'objet Clienten utilisant notre service et l'acceptons id. Et puis, par analogie avec la liste, nous renvoyons soit le statut 200 OK et l'objet lui-même Client, soit simplement le statut 404 Not Found, s'il n'y ida pas de client avec cela dans le système. Il reste à mettre en œuvre deux opérations - Mettre à jour et Supprimer. Voici le code de ces méthodes :
@PutMapping(value = "/clients/{id}")
public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Client client) {
   final boolean updated = clientService.update(client, id);

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

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

   return deleted
           ? new ResponseEntity<>(HttpStatus.OK)
           : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
}
Il n’y a rien de fondamentalement nouveau dans ces méthodes, nous allons donc sauter une description détaillée. La seule chose qui mérite d'être mentionnée est que la méthode updatetraite les requêtes PUT (annotation @PutMapping) et la méthode deletetraite les requêtes DELETE (annotation DeleteMapping). Voici le code complet du contrôleur :
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }

   @PostMapping(value = "/clients")
   public ResponseEntity<?> create(@RequestBody Client client) {
       clientService.create(client);
       return new ResponseEntity<>(HttpStatus.CREATED);
   }

   @GetMapping(value = "/clients")
   public ResponseEntity<List<Client>> read() {
       final List<client> clients = clientService.readAll();

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

   @GetMapping(value = "/clients/{id}")
   public ResponseEntity<Client> read(@PathVariable(name = "id") int id) {
       final Client client = clientService.read(id);

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

   @PutMapping(value = "/clients/{id}")
   public ResponseEntity<?> update(@PathVariable(name = "id") int id, @RequestBody Client client) {
       final boolean updated = clientService.update(client, id);

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

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

       return deleted
               ? new ResponseEntity<>(HttpStatus.OK)
               : new ResponseEntity<>(HttpStatus.NOT_MODIFIED);
   }
}
En conséquence, la structure de notre projet ressemble à ceci : Présentation de REST.  Partie 3 : Création d'un service RESTful dans Spring Boot - 7

Lancement et tests

Pour exécuter notre application, exécutez simplement la méthode maindans la classe RestExampleApplication. Et pour tester les services Web RESTful, vous devez télécharger un nouveau logiciel.) Le fait est que les requêtes GET sont assez faciles à envoyer à partir d'un navigateur classique, mais pour POST, PUT et DELETE, un navigateur classique ne suffit pas. Ne vous inquiétez pas : vous pouvez utiliser Postman pour envoyer n'importe quelle requête HTTP. Vous pouvez le télécharger à partir d'ici . Après le téléchargement et l'installation, nous commençons à tester notre application. Pour ce faire, ouvrez le programme et créez une nouvelle demande : Présentation de REST.  Partie 3 : Création d'un service RESTful dans Spring Boot - 9Cliquez sur le bouton Nouveau dans le coin supérieur gauche. Ensuite, sélectionnez Requête : Présentation de REST.  Partie 3 : Création d'un service RESTful avec Spring Boot - 10Ensuite, donnez-lui un nom et enregistrez-la. Essayons maintenant d'envoyer une requête POST au serveur et de créer le premier client : Présentation de REST.  Partie 3 : Création d'un service RESTful dans Spring Boot - 11Nous créons ainsi plusieurs clients. Ensuite, nous changeons le type de requête en GET et l'envoyons au serveur : Présentation de REST.  Partie 3 : Création d'un service RESTful dans Spring Boot - 12

Résultats généraux

Félicitations : nous avons abordé tout un sujet de REST. Tout le matériel s'est avéré volumineux, mais nous espérons qu'il vous sera utile :
  1. Nous avons appris ce qu'est REST.

  2. Nous avons pris connaissance de l'histoire de REST.

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

    • amener l'architecture à un modèle client-serveur ;
    • manque de condition;
    • mise en cache ;
    • uniformité de l'interface;
    • couches;
    • code sur demande (restriction facultative).
  4. Nous avons examiné les avantages qu'offre REST

  5. Nous avons examiné en détail comment le serveur et le client interagissent les uns avec les autres à l'aide du protocole HTTP.

  6. Examinons de plus près les demandes et les réponses. Leurs composants ont été démontés.

  7. Enfin, nous sommes passés à la pratique et avons écrit notre propre petite application RESTful dans Spring Boot. Et nous avons même appris à le tester à l'aide du programme Postman.

Phew. Cela s'est avéré volumineux, mais il y a néanmoins quelque chose à faire comme devoirs.

Devoirs

Essayez ce qui suit :
  1. En suivant la description ci-dessus, créez votre propre projet Spring Boot et implémentez-y la même logique que dans la conférence. Répétez tout 1 en 1.
  2. Lancez-le. application.
  3. Téléchargez et configurez Postman (ou tout autre outil d'envoi de requêtes, même curl).
  4. Testez les requêtes POST et GET de la même manière que décrit dans le cours.
  5. Testez vous-même les requêtes PUT et DELETE.
Partie 1 : Qu'est-ce que REST Partie 2 : Communication entre client et serveur
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION