JavaRush /Blog Java /Random-VI /Tổng quan về REST. Phần 3: Tạo RESTful Service trong Spri...

Tổng quan về REST. Phần 3: Tạo RESTful Service trong Spring Boot

Xuất bản trong nhóm
Đây là phần cuối cùng của quá trình phân tích cú pháp REST. Ở các phần trước: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 1

Tạo một dự án

Trong phần này, chúng ta sẽ tạo một ứng dụng RESTful nhỏ bằng Spring Boot. Ứng dụng của chúng tôi sẽ triển khai các hoạt động CRUD (Tạo, Đọc, Cập nhật, Xóa) trên máy khách từ ví dụ ở phần cuối của phân tích. Trước tiên, hãy tạo một ứng dụng Spring Boot mới thông qua menu File -> New -> Project... Trong cửa sổ mở ra, chọn Spring Khởi tạo và chỉ định Project SDK: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 2Nhấp vào nút Tiếp theo. Trong cửa sổ tiếp theo, chỉ định loại dự án Maven, chỉ định Nhóm và Hiện vật: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 3Nhấp vào nút Tiếp theo. Trong cửa sổ tiếp theo, chúng ta cần lựa chọn các thành phần Spring Framework cần thiết cho dự án. Spring Web sẽ là đủ đối với chúng ta: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 4Nhấn vào nút Next. Tiếp theo, tất cả những gì còn lại là chỉ định tên dự án và vị trí của nó trong hệ thống tệp: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 5Nhấp vào nút Kết thúc. Dự án đã được tạo, bây giờ chúng ta có thể thấy cấu trúc của nó: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 6IDEA đã tạo cho chúng ta bộ mô tả triển khai hệ thống xây dựng Maven - pom.xml và lớp ứng dụng chính: RestExampleApplication. Đây là mã của họ:
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>
Ứng dụng RestExample:
@SpringBootApplication
public class RestExampleApplication {

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

}

Tạo chức năng REST

Ứng dụng của chúng tôi quản lý khách hàng. Vì vậy, điều đầu tiên chúng ta cần làm là tạo một thực thể khách hàng. Đây sẽ là một lớp POJO. Hãy tạo một gói modelbên trong một gói com.javarush.lectures.rest_example. modelHãy tạo một lớp bên trong gói 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;
   }
}
Dịch vụ sẽ triển khai các hoạt động CRUD trên máy khách. Bước tiếp theo là tạo một dịch vụ sẽ thực hiện các hoạt động này. Trong gói com.javarush.lectures.rest_examplechúng ta sẽ tạo một gói service, bên trong chúng ta sẽ tạo một giao diện ClientService. Đây là mã giao diện có ý kiến:
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);
}
Tiếp theo chúng ta cần tạo một triển khai giao diện này. Bây giờ nó sẽ hoạt động như một kho lưu trữ của khách hàng Map<Integer, Client>. Khóa thẻ sẽ là id khách hàng và giá trị sẽ là chính khách hàng đó. Điều này được thực hiện để không làm quá tải ví dụ với các chi tiết cụ thể khi làm việc với cơ sở dữ liệu. Tuy nhiên, trong tương lai, chúng tôi sẽ có thể viết một triển khai giao diện khác trong đó có thể kết nối cơ sở dữ liệu thực. Trong gói này, servicechúng tôi sẽ tạo một triển khai giao diện 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;
   }
}
Chú thích @Servicecho Spring biết rằng lớp này là một dịch vụ. Đây là một loại lớp đặc biệt trong đó một số logic nghiệp vụ của ứng dụng được triển khai. Sau đó, nhờ chú thích này, Spring sẽ cung cấp cho chúng ta một phiên bản của lớp này ở những nơi cần sử dụng Dependency Insert. Bây giờ là lúc tạo bộ điều khiển. Một lớp đặc biệt trong đó chúng tôi triển khai logic để xử lý các yêu cầu của máy khách đối với điểm cuối (URI). Để làm cho nó rõ ràng hơn, chúng ta sẽ tạo lớp này theo từng phần. Đầu tiên, hãy tự tạo lớp và giới thiệu phần phụ thuộc vào nó ClientService:
@RestController
public class ClientController {

   private final ClientService clientService;

   @Autowired
   public ClientController(ClientService clientService) {
       this.clientService = clientService;
   }
}
Hãy làm rõ các chú thích: @RestController - cho Spring biết rằng lớp này là bộ điều khiển REST. Những thứ kia. lớp này sẽ triển khai logic để xử lý các yêu cầu của khách hàng @Autowired - nói với Spring rằng một phần phụ thuộc cần được đưa vào nơi này. Chúng tôi chuyển giao diện cho hàm tạo ClientService. Chúng tôi đã đánh dấu việc triển khai dịch vụ này bằng một chú thích @Servicetrước đó và bây giờ Spring sẽ có thể chuyển một phiên bản triển khai này cho hàm tạo bộ điều khiển. Tiếp theo, chúng ta sẽ từng bước triển khai từng phương thức điều khiển để xử lý các hoạt động CRUD. Hãy bắt đầu với thao tác Tạo. Để làm điều này, hãy viết một phương thức create:
@PostMapping(value = "/clients")
public ResponseEntity<?> create(@RequestBody Client client) {
   clientService.create(client);
   return new ResponseEntity<>(HttpStatus.CREATED);
}
Hãy xem xét phương thức này: @PostMapping(value = "/clients")- ở đây chúng tôi muốn nói rằng phương thức này xử lý các yêu cầu POST tới địa chỉ /clients ResponseEntity<?>. ResponseEntity- một lớp đặc biệt để trả lời phản hồi. Sử dụng nó, sau này chúng ta có thể trả lại mã trạng thái HTTP cho máy khách. Phương thức lấy một tham số @RequestBody Client client, giá trị của tham số này được thay thế từ phần thân yêu cầu. Bản tóm tắt nói về điều này @RequestBody. Bên trong phần thân của phương thức, chúng ta gọi phương thức create trên dịch vụ đã tạo trước đó và chuyển nó sang bộ điều khiển máy khách được chấp nhận trong các tham số. Sau đó, chúng tôi trả về trạng thái 201 Đã tạo bằng cách tạo một đối tượng mới ResponseEntityvà chuyển giá trị enum cần thiết cho nó HttpStatus. Tiếp theo, chúng ta thực hiện thao tác Read: Đầu tiên, chúng ta thực hiện thao tác lấy danh sách tất cả các máy khách có sẵn:
@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);
}
Hãy bắt đầu phân tích: @GetMapping(value = "/clients")- mọi thứ đều tương tự như chú thích @PostMapping, chỉ bây giờ chúng tôi xử lý các yêu cầu GET. Lần này chúng tôi quay lại ResponseEntity<List<Client>>, chỉ lần này, ngoài trạng thái HTTP, chúng tôi cũng sẽ trả về phần nội dung phản hồi, đây sẽ là danh sách khách hàng. Trong bộ điều khiển Spring REST, tất cả các đối tượng POJO, cũng như các tập hợp đối tượng POJO được trả về dưới dạng nội dung phản hồi, sẽ tự động được tuần tự hóa thành JSON trừ khi có quy định rõ ràng khác. Chúng tôi khá hài lòng với điều này. Bên trong phương thức, sử dụng dịch vụ của chúng tôi, chúng tôi nhận được danh sách tất cả khách hàng. Tiếp theo, nếu danh sách không rỗng hoặc trống, chúng tôi trả về ResponseEntitydanh sách khách hàng và trạng thái HTTP 200 OK bằng cách sử dụng lớp. Nếu không, chúng tôi chỉ trả về trạng thái HTTP 404 Not Found. Tiếp theo, chúng tôi sẽ triển khai khả năng lấy khách hàng theo id của anh ấy:
@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);
}
Một điều mới là bây giờ chúng ta có một biến đường dẫn. Một biến được xác định trong URI. value = "/clients/{id}". Chúng tôi đã chỉ ra nó trong dấu ngoặc nhọn. Và trong các tham số của phương thức, chúng tôi chấp nhận nó dưới dạng intmột biến bằng cách sử dụng chú thích @PathVariable(name = "id"). Phương thức này sẽ chấp nhận các yêu cầu về uri có dạng /clients/{id}, trong đó thay vào {id}đó có thể có bất kỳ giá trị số nào. Giá trị này sau đó được chuyển đến một biến int id— tham số phương thức. Trong body chúng ta nhận được đối tượng Clientsử dụng dịch vụ của mình và được chấp nhận id. Và sau đó, bằng cách tương tự với danh sách, chúng tôi trả về trạng thái 200 OK và chính đối tượng đó Clienthoặc đơn giản là trạng thái 404 Không tìm thấy, nếu idkhông có ứng dụng khách nào có điều này trong hệ thống. Vẫn còn phải thực hiện hai thao tác - Cập nhật và Xóa. Đây là mã cho các phương pháp này:
@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);
}
Về cơ bản không có gì mới trong các phương pháp này, vì vậy chúng tôi sẽ bỏ qua phần mô tả chi tiết. Điều duy nhất đáng nói đến là phương thức updatexử lý các yêu cầu PUT (chú thích @PutMapping) và phương thức deletexử lý các yêu cầu DELETE (chú thích DeleteMapping). Đây là mã điều khiển hoàn chỉnh:
@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);
   }
}
Kết quả là cấu trúc dự án của chúng ta trông như thế này: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 7

Ra mắt và thử nghiệm

Để chạy ứng dụng của chúng ta, chỉ cần chạy phương thức maintrong lớp RestExampleApplication. Và để kiểm tra các dịch vụ web RESTful, bạn cần tải xuống phần mềm mới) Thực tế là các yêu cầu GET khá dễ gửi từ trình duyệt thông thường, nhưng đối với POST, PUT và DELETE, trình duyệt thông thường là không đủ. Đừng lo lắng: bạn có thể sử dụng Postman để gửi bất kỳ yêu cầu HTTP nào. Bạn có thể tải về từ đây . Sau khi tải xuống và cài đặt, chúng tôi bắt đầu thử nghiệm ứng dụng của mình. Để thực hiện việc này, hãy mở chương trình và tạo yêu cầu mới: Tổng quan về REST.  Phần 3: Tạo RESTful Service trong Spring Boot - 9Nhấp vào nút Mới ở góc trên bên trái. Tiếp theo chọn Yêu cầu: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 10Tiếp theo, đặt tên cho nó và lưu lại. Bây giờ chúng ta hãy thử gửi yêu cầu POST đến máy chủ và tạo ứng dụng khách đầu tiên: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 11Chúng tôi tạo một số ứng dụng khách theo cách này. Sau đó, chúng tôi thay đổi loại yêu cầu thành GET và gửi nó đến máy chủ: Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot - 12

Kết quả chung

Xin chúc mừng: chúng ta đã đề cập khá nhiều đến chủ đề REST. Tất cả tài liệu hóa ra rất đồ sộ, nhưng chúng tôi hy vọng nó sẽ hữu ích cho bạn:
  1. Chúng tôi đã học được REST là gì.

  2. Chúng ta đã làm quen với lịch sử của REST.

  3. Chúng tôi đã nói về những hạn chế và nguyên tắc của phong cách kiến ​​trúc này:

    • đưa kiến ​​trúc vào mô hình client-server;
    • thiếu điều kiện;
    • bộ nhớ đệm;
    • tính đồng nhất của giao diện;
    • lớp;
    • mã theo yêu cầu (hạn chế tùy chọn).
  4. Chúng tôi đã xem xét những lợi ích mà REST mang lại

  5. Chúng tôi đã kiểm tra chi tiết cách máy chủ và máy khách tương tác với nhau bằng giao thức HTTP.

  6. Chúng ta hãy xem xét kỹ hơn các yêu cầu và phản hồi. Các thành phần của chúng đã được tháo rời.

  7. Cuối cùng, chúng tôi chuyển sang thực hành và viết ứng dụng RESTful nhỏ của riêng mình trong Spring Boot. Và chúng tôi thậm chí còn học cách kiểm tra nó bằng chương trình Postman.

Phù. Nó hóa ra rất đồ sộ, nhưng tuy nhiên vẫn có việc phải làm như bài tập về nhà.

Bài tập về nhà

Hãy thử như sau:
  1. Làm theo mô tả ở trên, hãy tạo dự án Spring Boot của riêng bạn và triển khai logic tương tự như trong bài giảng. Lặp lại mọi thứ 1 trong 1.
  2. Khởi động nó. ứng dụng.
  3. Tải xuống và thiết lập Postman (hoặc bất kỳ công cụ nào khác để gửi yêu cầu, thậm chí là cuộn tròn).
  4. Kiểm tra các yêu cầu POST và GET tương tự như mô tả trong bài giảng.
  5. Tự mình kiểm tra các yêu cầu PUT và DELETE.
Phần 1: REST là gì Phần 2: Giao tiếp giữa client và server
Bình luận
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION