JavaRush /Java blogi /Random-UZ /REST haqida umumiy fikr. 3-qism: Spring Boot-da RESTful x...

REST haqida umumiy fikr. 3-qism: Spring Boot-da RESTful xizmatini yaratish

Guruhda nashr etilgan
Bu REST tahlilining yakuniy qismi. Oldingi qismlarda: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 1

Loyiha yaratish

Ushbu bo'limda biz Spring Boot yordamida kichik RESTful ilovasini yaratamiz. Bizning ilovamiz tahlilning oxirgi qismidagi misoldan mijozlarga CRUD (Yaratish, o'qish, yangilash, o'chirish) operatsiyalarini amalga oshiradi . Avval File -> New -> Project menyusi orqali yangi Spring Boot ilovasini yaratamiz ... Ochilgan oynada Spring Initializr ni tanlaymiz va Project SDK ni belgilaymiz: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 2Keyingi tugmasini bosing. Keyingi oynada Maven loyihasi turini belgilang, Guruh va Artifaktni belgilang: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 3Keyingi tugmasini bosing. Keyingi oynada biz loyiha uchun zarur bo'lgan Spring Framework komponentlarini tanlashimiz kerak. Spring Web biz uchun etarli bo'ladi: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 4Keyingi tugmasini bosing. Keyinchalik, faqat loyiha nomini va uning fayl tizimidagi o'rnini ko'rsatish qoladi: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 5Finish tugmasini bosing. Loyiha yaratildi, endi biz uning tuzilishini ko'rishimiz mumkin: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 6IDEA biz uchun Maven qurish tizimini joylashtirish deskriptorini - pom.xml va asosiy dastur sinfini yaratdi: RestExampleApplication. Mana ularning kodi:
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 funksiyasini yaratish

Bizning ilovamiz mijozlarni boshqaradi. Shunday qilib, biz qilishimiz kerak bo'lgan birinchi narsa - mijoz sub'ektini yaratish. Bu POJO sinfi bo'ladi. modelKeling , paket ichida paket yarataylik com.javarush.lectures.rest_example. Paket ichida modelsinf yaratamiz 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;
   }
}
Xizmat mijozda CRUD operatsiyalarini amalga oshiradi. Keyingi qadam bu operatsiyalarni amalga oshiradigan xizmatni yaratishdir. Paketda com.javarush.lectures.rest_examplebiz paket yaratamiz service, uning ichida interfeys yaratamiz ClientService. Mana sharhlar bilan interfeys kodi:
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);
}
Keyinchalik biz ushbu interfeysning amalga oshirilishini yaratishimiz kerak. Endi u mijoz ombori sifatida ishlaydi Map<Integer, Client>. Karta kaliti mijoz identifikatori bo'ladi va qiymat mijozning o'zi bo'ladi. Bu ma'lumotlar bazasi bilan ishlashning o'ziga xos xususiyatlari bilan misolni ortiqcha yuklamaslik uchun qilingan. Biroq, kelajakda biz haqiqiy ma'lumotlar bazasini ulash mumkin bo'lgan interfeysning yana bir ilovasini yozishimiz mumkin. Paketda servicebiz interfeysning amalga oshirilishini yaratamiz 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;
   }
}
Izoh @ServiceBahorga bu sinf xizmat ekanligini aytadi. Bu ilovaning ba'zi biznes mantiqlari amalga oshiriladigan maxsus sinf turi. Keyinchalik, ushbu izoh tufayli, Spring bizga Dependency Injection yordamida kerak bo'lgan joylarda ushbu sinfning namunasini taqdim etadi. Endi boshqaruvchini yaratish vaqti keldi. Biz so'nggi nuqtalar (URI) uchun mijoz so'rovlarini qayta ishlash mantiqini amalga oshiradigan maxsus sinf. Aniqroq qilish uchun biz ushbu sinfni qismlarga ajratamiz. Birinchidan, sinfning o'zini yaratamiz va unga bog'liqlikni kiritamiz ClientService:
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }
}
Izohlarga aniqlik kiritamiz: @RestController - Springga bu sinf REST kontrolleri ekanligini aytadi. Bular. bu sinf mijoz so'rovlarini qayta ishlash mantiqini amalga oshiradi @Autowired - Bahorga bu joyga qaramlikni kiritish kerakligini aytadi. Biz interfeysni konstruktorga o'tkazamiz ClientService. Biz ushbu xizmatni amalga oshirishni avvalroq izoh bilan belgilagan edik @Serviceva endi Spring ushbu amalga oshirishning namunasini kontroller konstruktoriga o'tkazishi mumkin bo'ladi. Keyinchalik, CRUD operatsiyalarini qayta ishlash uchun har bir kontroller usulini bosqichma-bosqich amalga oshiramiz. Yaratish operatsiyasidan boshlaylik. Buning uchun usulni yozamiz create:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
   clientService.create(client);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Keling, ushbu usulni ko'rib chiqaylik: @PostMapping(value = "/clients")- bu erda biz ushbu usul POST so'rovlarini /clients manziliga qayta ishlashni nazarda tutamiz.Usul qaytaradi ResponseEntity<?>. ResponseEntity- javoblarni qaytarish uchun maxsus sinf. Undan foydalanib, HTTP holat kodini keyinchalik mijozga qaytarishimiz mumkin. Usul parametrni oladi @RequestBody Client client, bu parametrning qiymati so'rov tanasidan almashtiriladi. Abstrakt bu haqda gapiradi @RequestBody. Usul tanasi ichida biz avval yaratilgan xizmatda yaratish usulini chaqiramiz va parametrlarda qabul qilingan mijoz nazoratchisiga o'tamiz. ResponseEntityKeyin yangi ob'ekt yaratish va unga kerakli enum qiymatini o'tkazish orqali 201 Created holatini qaytaramiz HttpStatus. Keyinchalik, biz operatsiyani amalga oshiramiz Read: Birinchidan, biz barcha mavjud mijozlar ro'yxatini olish operatsiyasini amalga oshiramiz:
@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);
}
Tahlilni boshlaymiz: @GetMapping(value = "/clients")- hamma narsa izohga o'xshaydi @PostMapping, faqat hozir biz GET so'rovlarini qayta ishlaymiz. Bu safar biz qaytamiz ResponseEntity<List<Client>>, faqat bu safar, HTTP holatiga qo'shimcha ravishda, mijozlar ro'yxati bo'lgan javob organini ham qaytaramiz. Spring REST kontrollerlarida barcha POJO ob'ektlari, shuningdek javob organlari sifatida qaytariladigan POJO ob'ektlari to'plamlari, agar boshqacha ko'rsatilmagan bo'lsa, avtomatik ravishda JSONga seriyalashtiriladi. Bu bizga juda mos keladi. Usul ichida bizning xizmatimizdan foydalanib, biz barcha mijozlarning ro'yxatini olamiz. Keyinchalik, agar ro'yxat null yoki bo'sh bo'lmasa, biz ResponseEntitysinfdan foydalanib, mijozlar ro'yxatini va HTTP holatini 200 OK qaytaramiz. Aks holda, biz shunchaki HTTP holatini qaytaramiz 404 topilmadi. Keyinchalik, mijozni uning identifikatori bo'yicha qabul qilish imkoniyatini amalga oshiramiz:
@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);
}
Yangi narsa shundaki, bizda endi yo'l o'zgaruvchisi mavjud. URI da aniqlangan o'zgaruvchi. value = "/clients/{id}". Biz buni jingalak qavslarda ko'rsatdik. Va usul parametrlarida biz intizoh yordamida uni o'zgaruvchi sifatida qabul qilamiz @PathVariable(name = "id"). Bu usul formaning uri so'rovlarini qabul qiladi /clients/{id}, buning o'rniga {id}har qanday raqamli qiymat bo'lishi mumkin. Bu qiymat keyinchalik o'zgaruvchiga int id- usul parametriga o'tkaziladi. Tanada biz ob'ektni Clientxizmatimizdan foydalanib qabul qilamiz va qabul qilamiz id. Va keyin, ro'yxatga o'xshatib, biz 200 OK holatini va ob'ektning o'zini Clientyoki oddiygina 404 topilmadi holatini qaytaramiz, agar idtizimda bunday mijoz bo'lmasa. Ikkita operatsiyani bajarish qoladi - Yangilash va O'chirish. Mana bu usullar uchun kod:
@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);
}
Ushbu usullarda yangi narsa yo'q, shuning uchun biz batafsil tavsifni o'tkazib yuboramiz. Shuni ta'kidlash kerakki, usul updatePUT so'rovlarini qayta ishlaydi (annotatsiya @PutMapping) va usul deleteDELETE so'rovlarini qayta ishlaydi (annotatsiya DeleteMapping). Mana to'liq kontroller kodi:
@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);
   }
}
Natijada, loyihamizning tuzilishi quyidagicha ko'rinadi: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 7

Ishga tushirish va sinovdan o'tkazish

Ilovamizni ishga tushirish uchun mainsinfdagi usulni ishga tushirish kifoya RestExampleApplication. Va RESTful veb-xizmatlarini sinab ko'rish uchun siz yangi dasturiy ta'minotni yuklab olishingiz kerak) Gap shundaki, GET so'rovlarini oddiy brauzerdan yuborish juda oson, ammo POST, PUT va DELETE uchun oddiy brauzer etarli emas. Xavotir olmang: har qanday HTTP so'rovlarini yuborish uchun Postman dan foydalanishingiz mumkin. Bu yerdan yuklab olishingiz mumkin . Yuklab olish va o'rnatishdan so'ng biz dasturimizni sinab ko'rishni boshlaymiz. Buning uchun dasturni oching va yangi so'rov yarating: REST haqida umumiy fikr.  3-qism: Spring Boot-da RESTful xizmatini yaratish - 9Yuqori chap burchakdagi Yangi tugmasini bosing. Keyin, So'rovni tanlang: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 10Keyin, unga nom bering va uni saqlang. Keling, serverga POST so'rovini yuborishga harakat qilaylik va birinchi mijozni yaratamiz: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 11Biz shu tarzda bir nechta mijozlarni yaratamiz. Keyin so'rov turini GET ga o'zgartiramiz va uni serverga yuboramiz: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 12

Umumiy natijalar

Tabriklaymiz: biz REST mavzusini to'liq qamrab oldik. Barcha materiallar hajmli bo'lib chiqdi, ammo bu siz uchun foydali bo'ladi deb umid qilamiz:
  1. Biz REST nima ekanligini bilib oldik.

  2. Biz REST tarixi bilan tanishdik.

  3. Biz ushbu me'moriy uslubning cheklovlari va tamoyillari haqida gaplashdik:

    • arxitekturani mijoz-server modeliga olib kelish;
    • holatning yo'qligi;
    • keshlash;
    • interfeysning bir xilligi;
    • qatlamlar;
    • talab bo'yicha kod (ixtiyoriy cheklash).
  4. Biz REST taqdim etgan afzalliklarni ko'rib chiqdik

  5. Biz HTTP protokoli yordamida server va mijozning bir-birlari bilan qanday o'zaro aloqalarini batafsil ko'rib chiqdik.

  6. Keling, so'rovlar va javoblarni batafsil ko'rib chiqaylik. Ularning tarkibiy qismlari demontaj qilingan.

  7. Nihoyat, biz amaliyotga o'tdik va Spring Boot-da o'zimizning RESTful dasturimizni yozdik. Va biz hatto Postman dasturi yordamida uni qanday sinab ko'rishni o'rgandik.

Voy. Bu katta hajmli bo'lib chiqdi, ammo shunga qaramay, uy vazifasi sifatida qiladigan narsa bor.

Uy vazifasi

Quyidagilarni sinab ko'ring:
  1. Yuqoridagi tavsifdan so'ng, o'zingizning Spring Boot loyihangizni yarating va unda ma'ruzadagi kabi mantiqni amalga oshiring. Hammasini 1 dan 1 marta takrorlang.
  2. Uni ishga tushiring. ilova.
  3. Yuklab oling va sozlang Postman (yoki so'rovlarni yuborish uchun boshqa vosita, hatto curl).
  4. POST va GET so'rovlarini ma'ruzada ko'rsatilgan tarzda sinab ko'ring.
  5. PUT va DELETE so‘rovlarini o‘zingiz sinab ko‘ring.
1-qism: REST nima 2-qism: Mijoz va server o'rtasidagi aloqa
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION