CRUD — это акроним из четырёх операций: Create (Создание), Read (Чтение), Update (Обновление) и Delete (Удаление). В контексте REST API, CRUD соответствует следующему набору HTTP-методов:
| Операция (CRUD) | HTTP-метод | Назначение |
|---|---|---|
| Create | POST | Создание нового ресурса |
| Read | GET | Получение данных ресурса |
| Update | PUT/PATCH | Изменение существующего ресурса |
| Delete | DELETE | Удаление ресурса |
Создание CRUD API — это основа для взаимодействия с любыми ресурсами в веб-приложении. Давайте построим своё первое полноценное REST API для управления, скажем, сущностью Product.
Разработка сущностей и репозиториев
Создание сущности Product
Для работы с данными в базе в Spring мы используем аннотации JPA (Java Persistence API). Создадим класс Product, который будет представлять нашу сущность.
package com.example.demo.model;
import jakarta.persistence.*;
// Аннотация @Entity делает класс сущностью JPA
@Entity
@Table(name = "products") // Название таблицы в базе данных
public class Product {
@Id // Первичный ключ
@GeneratedValue(strategy = GenerationType.IDENTITY) // Автоинкремент
private Long id;
@Column(nullable = false) // Поле не должно быть null
private String name;
private String description;
@Column(nullable = false)
private Double price;
// Геттеры и сеттеры (для работы с полями через Hibernate)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
Создание репозитория
Для взаимодействия с базой данных мы используем интерфейсы Spring Data JPA, такие как JpaRepository. Создадим репозиторий для сущности Product.
package com.example.demo.repository;
import com.example.demo.model.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
// Репозиторий для работы с Product
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}
С помощью этого репозитория мы будем выполнять все базовые операции с базой данных: сохранение, получение, удаление и обновление записей.
Реализация CRUD-контроллеров
Теперь давайте создадим REST-контроллер, который будет выполнять CRUD-операции.
Создание CRUD-контроллера
package com.example.demo.controller;
import com.example.demo.model.Product;
import com.example.demo.repository.ProductRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
// Аннотация @RestController указывает, что это RESTful контроллер
@RestController
@RequestMapping("/api/products") // Базовый маршрут для всех запросов
public class ProductController {
private final ProductRepository productRepository;
// Внедрение зависимости через конструктор
public ProductController(ProductRepository productRepository) {
this.productRepository = productRepository;
}
// Чтение всех продуктов (Read - GET)
@GetMapping
public List<Product> getAllProducts() {
return productRepository.findAll();
}
// Чтение продукта по ID (Read - GET)
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
return productRepository.findById(id)
.map(product -> ResponseEntity.ok(product))
.orElse(ResponseEntity.notFound().build());
}
// Создание нового продукта (Create - POST)
@PostMapping
public ResponseEntity<Product> createProduct(@RequestBody Product product) {
Product savedProduct = productRepository.save(product);
return ResponseEntity.status(HttpStatus.CREATED).body(savedProduct);
}
// Обновление существующего продукта (Update - PUT)
@PutMapping("/{id}")
public ResponseEntity<Product> updateProduct(@PathVariable Long id, @RequestBody Product productDetails) {
return productRepository.findById(id)
.map(existingProduct -> {
existingProduct.setName(productDetails.getName());
existingProduct.setDescription(productDetails.getDescription());
existingProduct.setPrice(productDetails.getPrice());
Product updatedProduct = productRepository.save(existingProduct);
return ResponseEntity.ok(updatedProduct);
})
.orElse(ResponseEntity.notFound().build());
}
// Удаление продукта (Delete - DELETE)
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteProduct(@PathVariable Long id) {
return productRepository.findById(id)
.map(product -> {
productRepository.delete(product);
return ResponseEntity.noContent().build();
})
.orElse(ResponseEntity.notFound().build());
}
}
REST API для операций CRUD готов. Добавим ещё немного практики.
Практическое задание: проверка работы API
Запустите приложение и убедитесь, что оно работает. Вот несколько примеров запросов, которые можно выполнить с помощью Postman или curl.
Создание продукта (POST)
Запрос:
POST /api/products
Content-Type: application/json
{
"name": "Laptop",
"description": "A powerful gaming laptop",
"price": 1500.0
}
Ответ:
{
"id": 1,
"name": "Laptop",
"description": "A powerful gaming laptop",
"price": 1500.0
}
Получение всех продуктов (GET)
Запрос:
GET /api/products
Ответ:
[
{
"id": 1,
"name": "Laptop",
"description": "A powerful gaming laptop",
"price": 1500.0
}
]
Обновление продукта (PUT)
Запрос:
PUT /api/products/1
Content-Type: application/json
{
"name": "Laptop Pro",
"description": "An even more powerful gaming laptop",
"price": 2000.0
}
Ответ:
{
"id": 1,
"name": "Laptop Pro",
"description": "An even more powerful gaming laptop",
"price": 2000.0
}
Удаление продукта (DELETE)
Запрос:
DELETE /api/products/1
Ответ:
204 No Content
Типичные ошибки и их решение
Ошибка: Resource Not Found (404)
Если вы передаёте неверный ID ресурса, то приложение возвращает 404 Not Found. Это корректное поведение.
Совет: всегда проверяйте ID перед запросом, чтобы избежать лишней обработки.
Ошибка: Invalid JSON Body
Если тело запроса не соответствует ожидаемому формату, вы получите ошибку 400 Bad Request.
Совет: убедитесь, что ваш JSON сформирован корректно, и используйте встроенные инструменты в Postman или IDE для валидации.
Как это используется в реальных проектах
Создание REST API — это основа для большинства современных веб-приложений. Потенциальные сценарии:
- Управление каталогом товаров для интернет-магазина.
- Интеграция с мобильными устройствами для доставки данных.
- Взаимодействие между микросервисами через REST API.
Ваши CRUD API — это базовый строительный блок любого серверного проекта. Поэтому отточите свой навык до совершенства, ведь от него зависит успех вашего приложения.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ