JavaRush /Блоги Java /Random-TG /Баррасии REST. Қисми 3: Эҷоди хидмати RESTful дар Boot Sp...

Баррасии REST. Қисми 3: Эҷоди хидмати RESTful дар Boot Spring

Дар гурӯҳ нашр шудааст
Ин қисми ниҳоии таҳлor REST мебошад. Дар қисмҳои қаблӣ: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 1

Эҷоди лоиҳа

Дар ин бахш мо бо истифода аз Spring Boot як барномаи хурди RESTful эҷод мекунем. Замимаи мо амалиёти CRUD (Эҷод, Хондан, Навсозӣ, Нест кардан) -ро дар мизоҷ аз мисоли қисми охирини таҳлил амалӣ хоҳад кард. Аввалан, биёед барномаи нави Spring Boot-ро тавассути менюи File -> New -> Project созем... Дар равзанаи кушодашуда Spring Initializr-ро интихоб намуда Project SDK-ро муайян кунед: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 2Тугмаи Next-ро пахш кунед. Дар равзанаи навбатӣ намуди лоиҳаи Maven-ро муайян кунед, Гурӯҳ ва Артефактро муайян кунед: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 3Тугмаи Next-ро пахш кунед. Дар равзанаи навбатӣ, мо бояд ҷузъҳои Spring Framework-ро, ки барои лоиҳа заруранд, интихоб кунем. Веби баҳорӣ барои мо кофӣ хоҳад буд: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 4Тугмаи Ояндаро пахш кунед. Баъдан, танҳо муайян кардани номи лоиҳа ва ҷойгиршавии он дар системаи файлӣ боқӣ мемонад: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 5Тугмаи Finish -ро пахш кунед. Лоиҳа сохта шудааст, ҳоло мо метавонем сохтори онро бубинем: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 6IDEA барои мо дескриптори густариши системаи Maven build - pom.xml ва синфи асосии барномаро тавлид кардааст: RestExampleApplication. Ин аст рамзи онҳо:
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);
   }

}

Эҷоди функсияи REST

Замимаи мо мизоҷонро идора мекунад. Пас, аввалин чизе, ки мо бояд анҷом диҳем, эҷоди як ширкати муштарӣ аст. Ин синфи POJO хоҳад буд. Биёед modelдар дохor баста баста эҷод кунем com.javarush.lectures.rest_example. Биёед дар дохor баста modelсинф эҷод кунем 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;
   }
}
Хизматрасонӣ амалиёти CRUD-ро дар муштарӣ амалӣ хоҳад кард. Қадами навбатӣ эҷоди хидматест, ки ин амалиётҳоро амалӣ мекунад. Дар баста com.javarush.lectures.rest_exampleмо бастаеро месозем service, ки дар дохor он интерфейс эҷод мекунем ClientService. Ин аст рамзи интерфейс бо шарҳҳо:
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);
}
Минбаъд мо бояд татбиқи ин интерфейсро эҷод кунем. Акнун он ҳамчун анбори муштарӣ амал хоҳад кард Map<Integer, Client>. Калиди корт ID муштарӣ хоҳад буд ва арзиш худи муштарӣ хоҳад буд. Ин барои он анҷом дода шуд, ки мисолро бо хусусиятҳои кор бо базаи маълумот аз ҳад зиёд пур накунед. Аммо, дар оянда мо метавонем татбиқи дигари интерфейсро нависем, ки дар он пойгоҳи додаҳои воқеиро пайваст кардан мумкин аст. Дар баста serviceмо татбиқи интерфейсро эҷод мекунем 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;
   }
}
Эзоҳ @Serviceба Баҳор мегӯяд, ки ин синф хидмат аст. Ин як навъи махсуси синф аст, ки дар он баъзе мантиқи тиҷоратии барнома амалӣ карда мешавад. Минбаъд, ба шарофати ин эзоҳ, Spring ба мо намунаи ин синфро дар ҷойҳое пешкаш мекунад, ки он бо истифода аз Injection Dependency лозим аст. Ҳоло вақти сохтани контроллер аст. Синфи махсусе, ки дар он мо мантиқи коркарди дархостҳои муштариро барои нуқтаҳои ниҳоӣ (URI) амалӣ месозем. Барои равшантар кардани он, мо ин синфро қисмҳо эҷод мекунем. Аввалан, биёед худи синфро эҷод кунем ва аз он вобастагӣ ҷорӣ кунем ClientService:
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }
}
Биёед эзоҳҳоро равшан кунем: @RestController - ба Spring мегӯяд, ки ин синф контролери REST аст. Онхое. ин синф мантиқи коркарди дархостҳои муштариёнро амалӣ хоҳад кард @Autowired - ба Баҳор мегӯяд, ки вобастагӣ бояд дар ин ҷой ворид карда шавад. Мо интерфейсро ба конструктор мегузорем ClientService. Мо татбиқи ин хидматро @Serviceқаблан бо эзоҳ қайд карда будем ва акнун Spring метавонад як мисоли ин татбиқро ба конструктори контроллер гузаронад. Минбаъд, мо қадам ба қадам ҳар як усули контроллерро барои коркарди амалиёти CRUD татбиқ хоҳем кард. Биёед бо амалиёти Эҷод оғоз кунем. Барои ин, биёед як усулро нависед create:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
   clientService.create(client);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Биёед ин усулро дида бароем: @PostMapping(value = "/clients")- ин ҷо маънои онро дорад, ки ин усул дархостҳои POST-ро ба суроғаи /clients коркард мекунад.Усул бар мегардонад ResponseEntity<?>. ResponseEntity- синфи махсус барои баргардонидани ҷавобҳо. Бо истифода аз он, мо метавонем баъдтар рамзи ҳолати HTTP-ро ба муштарӣ баргардонем. Усул параметреро мегирад @RequestBody Client client, ки арзиши ин параметр аз мақоми дархост иваз карда мешавад. Дар реферат дар ин бора сухан меравад @RequestBody. Дар дохor бадани метод, мо усули эҷодро дар хидмати қаблан сохташуда меномем ва ба он контролери муштарӣ, ки дар параметрҳо қабул шудааст, мегузарем. Сипас, мо ҳолати 201 Сохташударо тавассути эҷоди an objectи нав ResponseEntityва интиқоли арзиши зарурии рақамӣ ба он бармегардонем HttpStatus. Баъдан, мо амалиётро иҷро мекунем Read: Аввалан, мо амалиёти гирифтани рӯйхати ҳамаи муштариёни дастрасро амалӣ менамоем:
@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")- ҳама чиз ба тавзеҳот монанд аст @PostMapping, танҳо ҳоло мо дархостҳои GET-ро коркард мекунем. Ин дафъа мо бармегардем ResponseEntity<List<Client>>, танҳо ин дафъа, ба ғайр аз ҳолати HTTP, мо инчунин мақоми посухро бармегардонем, ки он рӯйхати муштариён хоҳад буд. Дар контроллерҳои Spring REST, ҳама an objectҳои POJO, инчунин коллексияи an objectҳои POJO, ки ҳамчун мақомоти ҷавобӣ баргардонида мешаванд, ба таври худкор ба JSON силсила карда мешаванд, агар тартиби дигаре мушаххас нашуда бошад. Ин ба мо хеле мувофик аст. Дар дохor усул, бо истифода аз хидмати мо, мо рӯйхати ҳамаи муштариёнро мегирем. Баъдан, агар рӯйхат холӣ ё холӣ набошад, мо ResponseEntityбо истифода аз синф рӯйхати муштариён ва ҳолати HTTP 200 OK -ро бармегардонем. Дар акси ҳол, мо танҳо ҳолати HTTP-ро бармегардонем 404 ёфт нашуд. Минбаъд, мо қобorяти қабули муштариро аз рӯи 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);
}
Як чизи нав ин аст, ки мо ҳоло як тағирёбандаи роҳ дорем. Тағйирёбанда, ки дар URI муайян шудааст. value = "/clients/{id}". Мо онро дар қавсҳои ҷингила нишон додем. Ва дар параметрҳои метод мо онро ҳамчун intтағирёбанда бо истифода аз эзоҳ қабул мекунем @PathVariable(name = "id"). Ин усул дархостҳоро барои uri-и форма қабул мекунад /clients/{id}, ки дар он ҷо {id}ҳар гуна арзиши ададӣ вуҷуд дошта метавонад. Ин арзиш баъдан ба тағирёбанда int id- параметри усул интиқол дода мешавад. Дар бадан мо an objectро Clientбо истифода аз хидмати худ қабул мекунем ва қабул мекунем id. Ва он гоҳ, дар муқоиса бо рӯйхат, мо ҳолати 200 OK ва худи an objectро бармегардонем Clientё танҳо ҳолати 404 Наёфтанд, агар idдар система муштарӣ бо ин мавҷуд набошад. Иҷрои ду амалиёт боқӣ мемонад - Навсозӣ ва Нобуд. Ин аст рамзи ин усулҳо:
@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);
}
Дар ин усулҳо ҳеҷ чизи наве нест, бинобар ин мо тавсифи муфассалро мегузорем. Ягона чизе, ки бояд қайд кард, он аст, ки усул updateдархостҳои PUT-ро коркард мекунад (annotation @PutMapping) ва метод deleteдархостҳои DELETE-ро коркард мекунад (annotation DeleteMapping). Ин аст рамзи пурраи контроллер:
@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);
   }
}
Дар натиҷа сохтори лоиҳаи мо чунин менамояд: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 7

Оғоз ва озмоиш

Барои иҷро кардани замимаи мо, танҳо методро mainдар синф иҷро кунед RestExampleApplication. Ва барои санҷидани хидматҳои веби RESTful, шумо бояд нармафзори навро зеркашӣ кунед) Гап дар он аст, ки дархостҳои GET аз браузери муқаррарӣ фиристодан хеле осон аст, аммо барои POST, PUT ва DELETE браузери муқаррарӣ кофӣ нест. Парво накунед: шумо метавонед Postman-ро барои фиристодани ҳама гуна дархостҳои HTTP истифода баред. Шумо метавонед онро аз ин ҷо зеркашӣ кунед . Пас аз зеркашӣ ва насб, мо озмоиши замимаи худро оғоз мекунем. Барои ин, барномаро кушоед ва дархости нав эҷод кунед: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 9Тугмаи Навро дар кунҷи чапи боло пахш кунед. Баъдан, дархостро интихоб кунед: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful бо Boot Spring - 10Баъдан, ба он ном диҳед ва онро захира кунед. Биёед ҳоло кӯшиш кунем, ки дархости POST-ро ба server фиристем ва муштарии аввалро эҷод кунем: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 11Мо бо ин роҳ якчанд муштариро эҷод мекунем. Сипас, мо навъи дархостро ба GET иваз мекунем ва онро ба server мефиристем: Баррасии REST.  Қисми 3: Эҷоди хидмати RESTful дар Boot Spring - 12

Натиҷаҳои умумӣ

Табрик мекунем: мо мавзӯи REST-ро фаро гирифтем. Ҳама маводҳо ҳаҷм буданд, аммо мо умедворем, ки он барои шумо муфид хоҳад буд:
  1. Мо фаҳмидем, ки REST чист.

  2. Мо бо таърихи REST шинос шудем.

  3. Мо дар бораи маҳдудиятҳо ва принсипҳои ин услуби меъморӣ сӯҳбат кардем:

    • овардани меъморӣ ба модели муштарӣ-server;
    • набудани шароит;
    • кэш;
    • яксонии интерфейс;
    • қабатҳо;
    • code оид ба дархост (маҳдудияти ихтиёрӣ).
  4. Мо бартариҳоеро, ки REST таъмин мекунад, тафтиш кардем

  5. Мо ба таври муфассал дида баромадем, ки чӣ гуна server ва муштарӣ бо истифода аз протоколи HTTP бо ҳамдигар ҳамкорӣ мекунанд.

  6. Биёед ба дархостҳо ва посухҳо муфассалтар назар андозем. Компонентхои онхо чудо карда шуданд.

  7. Ниҳоят, мо ба амалия гузаштем ва барномаи хурди RESTful-и худро дар Spring Boot навиштем. Ва мо ҳатто бо истифода аз барномаи Postman чӣ гуна санҷидани онро омӯхтем.

Фу. Маълум шуд, ки ҳаҷмӣ буд, аммо ба ҳар ҳол чизе барои иҷрои вазифаи хонагӣ вуҷуд дорад.

Вазифаи хонагӣ

Инҳоро санҷед:
  1. Пас аз тавсифи дар боло тавсифшуда, лоиҳаи Spring Boot-и худро эҷод кунед ва ҳамон мантиқи дар лексияро дар он татбиқ кунед. Ҳама чизро 1 дар 1 такрор кунед.
  2. Онро оғоз кунед. ариза.
  3. Почтачин (ё ягон асбоби дигар барои фиристодани дархостҳо, ҳатто curl) -ро зеркашӣ ва насб кунед.
  4. Дархостҳои POST ва GET-ро ҳамон тавре, ки дар лексия тавсиф шудааст, санҷед.
  5. Дархостҳои PUT ва DELETE -ро худатон санҷед.
Қисми 1: REST чист Қисми 2: Муошират байни муштарӣ ва server
Шарҳҳо
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION