JavaRush /Java Blog /Random-TL /Pangkalahatang-ideya ng REST. Bahagi 3: Paglikha ng isang...

Pangkalahatang-ideya ng REST. Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot

Nai-publish sa grupo
Ito ang huling bahagi ng REST parsing. Sa mga nakaraang bahagi: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 1

Paglikha ng isang Proyekto

Sa seksyong ito, gagawa kami ng isang maliit na RESTful application gamit ang Spring Boot. Ipapatupad ng aming application ang mga operasyong CRUD (Gumawa, Magbasa, Mag-update, Magtanggal) sa mga kliyente mula sa halimbawa mula sa huling bahagi ng pagsusuri. Una, gumawa tayo ng bagong Spring Boot application sa pamamagitan ng menu File -> New -> Project... Sa window na bubukas, piliin ang Spring Initializr at tukuyin ang Project SDK: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 2I-click ang Next button. Sa susunod na window, tukuyin ang uri ng proyekto ng Maven, tukuyin ang Grupo at Artifact: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 3I-click ang pindutang Susunod. Sa susunod na window, kailangan nating piliin ang mga bahagi ng Spring Framework na kailangan para sa proyekto. Sapat na para sa amin ang Spring Web: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 4I-click ang button na Susunod. Susunod, ang natitira na lang ay tukuyin ang pangalan ng proyekto at ang lokasyon nito sa file system: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 5I-click ang Finish button. Nagawa na ang proyekto, ngayon ay makikita na natin ang istraktura nito: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 6Ang IDEA ay nakabuo para sa atin ng Maven build system deployment descriptor - pom.xml at ang pangunahing klase ng aplikasyon: RestExampleApplication. Narito ang kanilang 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);
   }

}

Gumagawa ng REST functionality

Ang aming application ay namamahala sa mga kliyente. Kaya ang unang bagay na kailangan nating gawin ay lumikha ng entity ng customer. Magiging POJO class ito. Gumawa tayo ng package modelsa loob ng package com.javarush.lectures.rest_example. modelGumawa tayo ng klase sa loob ng package Client:
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;
   }
}
Ipapatupad ng serbisyo ang mga pagpapatakbo ng CRUD sa kliyente. Ang susunod na hakbang ay lumikha ng isang serbisyo na magpapatupad ng mga operasyong ito. Sa pakete com.javarush.lectures.rest_exampleay gagawa tayo ng isang pakete service, sa loob kung saan gagawa tayo ng isang interface ClientService. Narito ang interface code na may mga komento:
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);
}
Susunod na kailangan naming lumikha ng isang pagpapatupad ng interface na ito. Ngayon ito ay kumilos bilang isang client repository Map<Integer, Client>. Ang card key ay ang client id, at ang value ay ang client mismo. Ginawa ito upang hindi ma-overload ang halimbawa sa mga detalye ng pagtatrabaho sa database. Gayunpaman, sa hinaharap ay makakapagsulat kami ng isa pang pagpapatupad ng interface kung saan posible na kumonekta sa isang tunay na database. Sa package servicegagawa kami ng pagpapatupad ng 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;
   }
}
Ang anotasyon @Serviceay nagsasabi sa Spring na ang klase na ito ay isang serbisyo. Ito ay isang espesyal na uri ng klase kung saan ipinatupad ang ilang lohika ng negosyo ng application. Kasunod nito, salamat sa anotasyong ito, magbibigay sa amin ang Spring ng isang instance ng klase na ito sa mga lugar kung saan kinakailangan ito gamit ang Dependency Injection. Ngayon ay oras na upang lumikha ng controller. Isang espesyal na klase kung saan ipinapatupad namin ang lohika para sa pagproseso ng mga kahilingan ng kliyente para sa mga endpoint (URI). Upang gawing mas malinaw, gagawin namin ang klase na ito sa mga bahagi. Una, likhain natin ang klase mismo at ipakilala ang isang dependency dito ClientService:
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }
}
Linawin natin ang mga anotasyon: @RestController - nagsasabi sa Spring na ang klase na ito ay isang REST controller. Yung. ipapatupad ng klase na ito ang lohika para sa pagproseso ng mga kahilingan ng kliyente @Autowired - nagsasabi sa Spring na kailangang mag-inject ng dependency sa lugar na ito. Ipinapasa namin ang interface sa tagabuo ClientService. Minarkahan namin ang pagpapatupad ng serbisyong ito ng isang anotasyon @Servicekanina, at ngayon ay maipapasa ng Spring ang isang instance ng pagpapatupad na ito sa tagabuo ng controller. Susunod, hakbang-hakbang naming ipapatupad ang bawat paraan ng controller para iproseso ang mga operasyon ng CRUD. Magsimula tayo sa operasyong Lumikha. Upang gawin ito, magsulat tayo ng isang pamamaraan create:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
   clientService.create(client);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Tingnan natin ang pamamaraang ito: @PostMapping(value = "/clients")- dito ang ibig sabihin ay pinoproseso ng pamamaraang ito ang mga kahilingan sa POST sa /clients address. Ang pamamaraan ay nagbabalik ResponseEntity<?>. ResponseEntity- isang espesyal na klase para sa pagbabalik ng mga tugon. Gamit ito, maaari naming ibalik ang HTTP status code sa kliyente. Ang pamamaraan ay tumatagal ng isang parameter @RequestBody Client client, ang halaga ng parameter na ito ay pinapalitan mula sa katawan ng kahilingan. Ang abstract ay nagsasalita tungkol dito @RequestBody. Sa loob ng katawan ng pamamaraan, tinatawag namin ang paraan ng paglikha sa naunang ginawang serbisyo at ipasa ito sa client controller na tinanggap sa mga parameter. Pagkatapos ay ibabalik namin ang status 201 Created sa pamamagitan ng paglikha ng isang bagong bagay ResponseEntityat pagpasa ng kinakailangang halaga ng enum dito HttpStatus. Susunod, ipinatupad namin ang operasyon Read: Una, ipinapatupad namin ang pagpapatakbo ng pagkuha ng isang listahan ng lahat ng magagamit na mga kliyente:
@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);
}
Simulan natin ang pagsusuri: @GetMapping(value = "/clients")- lahat ay katulad ng anotasyon @PostMapping, ngayon lang namin pinoproseso ang mga kahilingan sa GET. Sa pagkakataong ito ay babalik kami ResponseEntity<List<Client>>, sa pagkakataong ito lamang, bilang karagdagan sa status ng HTTP, ibabalik din namin ang katawan ng pagtugon, na magiging isang listahan ng mga kliyente. Sa Spring REST controllers, lahat ng POJO object, pati na rin ang mga koleksyon ng POJO objects na ibinalik bilang response body, ay awtomatikong naka-serialize sa JSON maliban kung tahasang tinukoy kung hindi man. Ito ay angkop sa amin. Sa loob ng pamamaraan, gamit ang aming serbisyo, nakakakuha kami ng isang listahan ng lahat ng mga kliyente. Susunod, kung ang listahan ay hindi null o walang laman, ibabalik namin ResponseEntityang listahan ng mga kliyente at ang HTTP status na 200 OK gamit ang klase. Kung hindi, ibinabalik lang namin ang status ng HTTP na 404 Not Found. Susunod, ipapatupad namin ang kakayahang makatanggap ng kliyente sa pamamagitan ng kanyang id:
@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);
}
May bago ay mayroon na tayong path variable. Isang variable na tinukoy sa isang URI. value = "/clients/{id}". Ipinahiwatig namin ito sa mga kulot na braces. At sa mga parameter ng pamamaraan tinatanggap namin ito bilang intisang variable gamit ang annotation @PathVariable(name = "id"). Ang pamamaraang ito ay tatanggap ng mga kahilingan para sa uri ng form /clients/{id}, kung saan sa halip {id}ay maaaring mayroong anumang numerong halaga. Ang halagang ito ay kasunod na ipinapasa sa isang variable int id—ang parameter ng pamamaraan. Sa katawan natatanggap namin ang bagay Clientgamit ang aming serbisyo at tinanggap id. At pagkatapos, sa pamamagitan ng pagkakatulad sa listahan, ibinabalik namin ang alinman sa 200 OK status at ang object mismo Client, o simpleng 404 Not Found status, kung walang idkliyente na may ganito sa system. Nananatili itong ipatupad ang dalawang operasyon - I-update at Tanggalin. Narito ang code para sa mga pamamaraang ito:
@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);
}
Walang mahalagang bago sa mga pamamaraang ito, kaya laktawan namin ang isang detalyadong paglalarawan. Ang tanging bagay na dapat banggitin ay ang pamamaraan updateay nagpoproseso ng mga kahilingan ng PUT (annotation @PutMapping), at ang pamamaraan deleteay nagpoproseso ng mga hiling na DELETE (annotation DeleteMapping). Narito ang kumpletong controller code:
@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);
   }
}
Bilang resulta, ang istraktura ng aming proyekto ay ganito ang hitsura: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 7

Ilunsad at pagsubok

Upang patakbuhin ang aming aplikasyon, patakbuhin lamang ang pamamaraan mainsa klase RestExampleApplication. At upang masubukan ang RESTful web services, kailangan mong mag-download ng bagong software) Ang katotohanan ay ang mga kahilingan sa GET ay medyo madaling ipadala mula sa isang regular na browser, ngunit para sa POST, PUT at DELETE ay hindi sapat ang isang regular na browser. Huwag mag-alala: maaari mong gamitin ang Postman upang magpadala ng anumang mga kahilingan sa HTTP. Maaari mong i-download ito mula dito . Pagkatapos mag-download at mag-install, sinimulan naming subukan ang aming application. Upang gawin ito, buksan ang programa at lumikha ng bagong kahilingan: Pangkalahatang-ideya ng REST.  Bahagi 3: Paglikha ng isang RESTful na Serbisyo sa Spring Boot - 9I-click ang pindutang Bagong sa kaliwang sulok sa itaas. Susunod, piliin ang Kahilingan: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 10Susunod, bigyan ito ng pangalan at i-save ito. Subukan nating magpadala ng POST na kahilingan sa server at gawin ang unang kliyente: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 11Lumilikha kami ng ilang kliyente sa ganitong paraan. Pagkatapos ay binago namin ang uri ng kahilingan sa GET at ipadala ito sa server: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 12

Pangkalahatang resulta

Binabati kita: natalakay na namin ang paksa ng REST. Ang lahat ng materyal ay naging napakalaki, ngunit inaasahan namin na ito ay magiging kapaki-pakinabang para sa iyo:
  1. Natutunan namin kung ano ang REST.

  2. Nakilala namin ang kasaysayan ng REST.

  3. Napag-usapan namin ang tungkol sa mga limitasyon at prinsipyo ng istilong arkitektura na ito:

    • pagdadala ng arkitektura sa isang modelo ng client-server;
    • kakulangan ng kondisyon;
    • pag-cache;
    • pagkakapareho ng interface;
    • mga layer;
    • code on demand (opsyonal na paghihigpit).
  4. Sinuri namin ang mga pakinabang na ibinibigay ng REST

  5. Sinuri namin nang detalyado kung paano nakikipag-ugnayan ang server at client sa isa't isa gamit ang HTTP protocol.

  6. Tingnan natin ang mga kahilingan at tugon. Ang kanilang mga bahagi ay na-disassemble.

  7. Sa wakas, lumipat kami sa pagsasanay at nagsulat ng sarili naming maliit na RESTful application sa Spring Boot. At natutunan pa namin kung paano subukan ito gamit ang programang Postman.

Phew. Ito ay naging napakalaki, ngunit gayunpaman mayroong isang bagay na dapat gawin bilang araling-bahay.

Takdang aralin

Subukan ang sumusunod:
  1. Kasunod ng paglalarawan sa itaas, lumikha ng iyong sariling proyekto sa Spring Boot at ipatupad ang parehong lohika dito tulad ng sa lecture. Ulitin ang lahat ng 1 sa 1.
  2. Ilunsad ito. aplikasyon.
  3. I-download at i-set up ang Postman (o anumang iba pang tool para sa pagpapadala ng mga kahilingan, kahit curl).
  4. Subukan ang mga kahilingan sa POST at GET sa parehong paraan tulad ng inilarawan sa lecture.
  5. Subukan ang PUT at DELETE na mga kahilingan sa iyong sarili.
Part 1: Ano ang REST Part 2: Communication sa pagitan ng client at server
Mga komento
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION