CodeGym /Java Blog /Random-IT /Panoramica di REST. Parte 3: creazione di un servizio RES...
John Squirrels
Livello 41
San Francisco

Panoramica di REST. Parte 3: creazione di un servizio RESTful su Spring Boot

Pubblicato nel gruppo Random-IT
Questa è la parte finale della nostra panoramica di REST. Nelle parti precedenti abbiamo trattato: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 1

Creazione di un progetto

In questa sezione creeremo una piccola applicazione RESTful utilizzando Spring Boot. La nostra applicazione implementerà le operazioni CRUD (Create, Read, Update, Delete) sui clienti dall'esempio nella parte precedente della panoramica. Per iniziare, creeremo una nuova applicazione Spring Boot tramite il menu: File -> Nuovo -> Progetto... Nella finestra che si apre, seleziona Spring Initializr e specifica l'SDK del progetto: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 2fai clic sul pulsante "Avanti". Nella finestra successiva, specifica "Maven Project" come tipo di progetto, specifica "Group" e "Artifact": Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 3fai clic sul pulsante "Next". Nella finestra successiva, dobbiamo selezionare i componenti Spring Framework necessari per il progetto. Spring Web ci basterà: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 4Fare clic sul pulsante "Avanti". Ora non resta che indicare il nome del progetto e la sua posizione nel file system: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 5fare clic sul pulsante "Fine". Il progetto è stato creato e ora possiamo vederne la struttura: IDEA ha generato per noi Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 6un descrittore di distribuzione Maven (pom.xml) e la classe principale dell'applicazione ( ). RestExampleApplicationEcco come appaiono:

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>
RestEsempioApplicazione:

@SpringBootApplication
public class RestExampleApplication {

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

}

Creazione della funzionalità REST

La nostra applicazione è un sistema di gestione dei clienti. Quindi, la prima cosa che dobbiamo fare è creare un'entità cliente. Sarà una classe POJO (plain old Java object). Creare un modelpacchetto all'interno del com.codegym.lessons.rest_examplepacchetto. All'interno del modelpacchetto, crea Customer:

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;
   }
}
Il servizio implementerà le operazioni CRUD sui clienti. Il passaggio successivo consiste nel creare un servizio che implementerà queste operazioni. Nel com.codegym.lessons.rest_examplepacchetto, crea un servicepacchetto. E al suo interno, crea CustomerServiceun'interfaccia. Ecco il codice dell'interfaccia con i commenti:

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);
}
Successivamente, dobbiamo implementare questa interfaccia. Ora Map<Integer, Customer>memorizzeremo i nostri clienti. Le chiavi della mappa saranno gli ID cliente ei valori saranno i clienti stessi. Questo viene fatto in modo da non sovraccaricare questo esempio con le specifiche di lavorare con un database reale. Tuttavia, in futuro potremo scrivere un'altra implementazione dell'interfaccia, che consentirà di connettersi a un vero database. Nel servicepacchetto, crea un'implementazione dell'interfaccia CustomerService:

@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' @Serviceannotazione dice a Spring che questa classe è un servizio. Si tratta di un tipo speciale di classe che implementa alcune logiche di applicazione aziendale. Successivamente, grazie a questa annotazione, Spring utilizzerà l'iniezione di dipendenza per fornirci un'istanza di questa classe in tutti i luoghi in cui è necessaria. Ora è il momento di creare un controller. Questa è una classe speciale in cui implementeremo la logica per l'elaborazione delle richieste dei client inviate agli endpoint (URI). Per rendere tutto questo più chiaro, creeremo questa classe in modo incrementale. Innanzitutto, crea la classe stessa e aggiungi una dipendenza su CustomerService:

@RestController
public class CustomerController {

   private final CustomerService customerService;

   @Autowired
   public CustomerController(CustomerService customerService) {
       this.customerService = customerService;
   }
}
Spieghiamo le annotazioni: @RestController dice a Spring che questa classe è un controller REST. In altre parole, questa classe implementa la logica per l'elaborazione delle richieste del client. @Autowired dice a Spring che è necessario aggiungere una dipendenza qui. Passiamo l' CustomerServiceinterfaccia al costruttore. In precedenza, abbiamo contrassegnato l'implementazione di questo servizio con l' @Serviceannotazione e ora Spring sarà in grado di passare un'istanza di questa implementazione al costruttore del controller. Successivamente, implementeremo ciascun metodo del controller per la gestione delle operazioni CRUD. Iniziamo con l'operazione di creazione. Per fare ciò, scriviamo un createmetodo:

@PostMapping(value = "/customers")
public ResponseEntity<?> create(@RequestBody Customer customer) {
   customerService.create(customer);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Analizziamo questo metodo: @PostMapping(value = "/customers")significa che questo metodo elabora le richieste POST inviate all'indirizzo "/clienti". Il metodo restituisce un ResponseEntity<?>. A ResponseEntityè una classe speciale per la restituzione delle risposte. Successivamente, lo useremo per restituire un codice di stato HTTP al client. Il metodo ha un @RequestBody Customer customerparametro. Il valore di questo parametro deriva dal corpo della richiesta. L' @RequestBodyannotazione lo indica. All'interno del corpo del metodo, chiamiamo il create()metodo sul servizio precedentemente creato e lo passiamo al controller del cliente ricevuto nei parametri. Quindi restituiamo lo stato "201 Created" creando un nuovo ResponseEntityoggetto e passandogli il HttpStatuscampo enum corrispondente. Successivamente, implementeremo ilreadoperazione: Innanzitutto, implementeremo l'operazione per ottenere un elenco di tutti i clienti disponibili:

@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);
}
Immergiamoci in: @GetMapping(value = "/customers")- tutto qui è simile all'annotazione @PostMapping, ma ora stiamo elaborando le richieste GET. Questa volta restituiamo un ResponseEntity<List<Customer>>, e oltre a uno stato HTTP, restituiremo anche un corpo della risposta, che sarà l'elenco dei clienti. Nei controller REST di Spring, tutto è costituito da oggetti POJO e raccolte di oggetti POJO, che vengono restituiti come corpi di risposta e serializzati automaticamente in JSON, se non diversamente specificato. Questo ci si addice perfettamente. All'interno del metodo, utilizziamo il nostro servizio per ottenere un elenco di tutti i clienti. Successivamente, se l'elenco non è nullo e non è vuoto, allora usiamo il fileResponseEntityclass per restituire l'elenco dei clienti e il codice di stato HTTP "200 OK". Altrimenti, restituiamo semplicemente il codice di stato HTTP "404 Not Found". Ora implementeremo la possibilità di ottenere un cliente utilizzando il suo 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);
}
Una novità qui è la variabile path. La variabile è definita nell'URI: value = "/customers/{id}". Lo indichiamo tra parentesi graffe. E lo riceviamo come intparametro di metodo usando l' @PathVariable(name = "id")annotazione. Questo metodo accetterà le richieste inviate agli URI nella forma /customers/{id}, dove {id}rappresenta qualsiasi valore numerico. Questo valore viene successivamente passato tramite la int idvariabile al parametro del metodo. Nel corpo, otteniamo l' Customeroggetto utilizzando il nostro servizio e il ricevuto id. E poi, per analogia con l'elenco, restituiamo lo stato "200 OK" e l' Customeroggetto stesso, o semplicemente lo stato "404 Not Found" se il sistema non ha clienti con quello id. Dobbiamo ancora implementare due operazioni: aggiornamento ed eliminazione. Ecco il codice per questi metodi:

@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);
}
Non c'è nulla di essenzialmente nuovo in questi metodi, quindi salteremo la descrizione dettagliata. L'unica cosa degna di nota è che il update()metodo gestisce le richieste PUT ( @PutMappingannotazione) e il delete()metodo gestisce le richieste DELETE ( DeleteMappingannotazione). Ecco il codice completo per il controller:

@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);
   }
}
Di conseguenza, la struttura del nostro progetto è la seguente: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 7

Lancio e test

Per avviare la nostra applicazione, basta eseguire il main()metodo nella RestExampleApplicationclasse. Ma per testare i servizi Web RESTful, dobbiamo scaricare software aggiuntivo. Il fatto è che le richieste GET sono abbastanza semplici da inviare da un normale browser, ma un normale browser non può inviare richieste POST, PUT e DELETE. Non preoccuparti: puoi utilizzare un programma chiamato Postman per inviare qualsiasi richiesta HTTP. Puoi scaricarlo qui . Dopo aver scaricato e installato Postman, iniziamo a testare la nostra applicazione. Per fare ciò, apri il programma e crea una nuova richiesta: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 9fai clic sul pulsante "Nuovo" nell'angolo in alto a sinistra. Quindi, seleziona "Richiedi": Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 10Quindi, assegnagli un nome e salvalo. Ora proviamo ad inviare una richiesta POST al server e creiamo il primo cliente: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 11Creiamo diversi clienti in questo modo. Quindi cambiamo il tipo di richiesta in GET e inviamo la richiesta al server: Panoramica di REST.  Parte 3: Creazione di un servizio RESTful su Spring Boot - 12

Riepilogo

Congratulazioni! Abbiamo coperto sufficientemente REST. C'era un grande volume di materiale, ma spero che ti sia stato utile:
  1. Abbiamo imparato cos'è REST.

  2. Abbiamo appreso come è nato REST.

  3. Abbiamo parlato dei limiti e dei principi alla base di questo stile architettonico:

    • architettura client-server
    • apolide
    • memorizzazione nella cache
    • interfaccia uniforme
    • strati
    • codice su richiesta (facoltativo)
  4. Abbiamo esplorato i vantaggi offerti da REST

  5. Abbiamo esaminato in dettaglio come il server e il client interagiscono tra loro tramite il protocollo HTTP.

  6. Abbiamo esaminato più da vicino le richieste e le risposte. Abbiamo sezionato le loro parti costitutive.

  7. Infine, abbiamo acquisito esperienza pratica scrivendo la nostra piccola applicazione RESTful utilizzando Spring Boot. E abbiamo anche imparato a testarlo usando Postman.

Accidenti. È stato molto, ma hai ancora qualcosa da fare come compiti a casa.

Compiti a casa

Prova quanto segue:
  1. Seguendo la descrizione precedente, crea il tuo progetto Spring Boot e implementa la stessa logica della lezione. Ripeti tutto esattamente.
  2. Avvia l'applicazione.
  3. Scarica e configura Postman (o qualsiasi altro strumento per l'invio di richieste, ad esempio curl).
  4. Testare le richieste POST e GET nello stesso modo descritto nella lezione.
  5. Testa tu stesso le richieste PUT e DELETE.
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION