Когда сервер предоставляет API, параметры и данные запросов играют ключевую роль в управлении ресурсами. Сегодня мы разберем:
- Обработку Query Parameters: фильтры и сортировку.
- Работу с Path Variables: динамические сегменты URI.
- Как обрабатывать ошибки, связанные с параметрами.
И, конечно же, напишем код! Потому что теория без практики — словно метод без реализации.
Что такое Query Parameters?
Начнем с Query Parameters. Это параметры, которые передаются клиентом в строке запроса после символа ?. Они используются для фильтрации, сортировки, поиска данных и других уточнений запроса.
Пример URL с Query Parameters:
https://api.myapp.com/products?category=electronics&sort=price&order=asc
- category=electronics: указывает фильтр по категории "электроника".
- sort=price: сигнализирует, что мы сортируем по цене.
- order=asc: добавляет уточнение, что сортировка восходящая.
Аннотация @RequestParam
Для того чтобы обработать Query Parameters в Spring, используется аннотация @RequestParam. Давайте посмотрим на пример кода:
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping
public List<Product> getProducts(
@RequestParam(required = false) String category,
@RequestParam(defaultValue = "name") String sort,
@RequestParam(defaultValue = "asc") String order
) {
// Логика фильтрации, сортировки
return productService.getProducts(category, sort, order);
}
}
@RequestParam(required = false): параметр не обязателен. Если клиент не передастcategory, он будет равенnull.defaultValue: задает значение по умолчанию, если параметр отсутствует в запросе.
Когда запрос отправляется на /products?category=clothing, в методе getProducts переменная category будет иметь значение "clothing", а sort и order примут значения по умолчанию.
Что такое Path Variables?
Path Variables (переменные пути) — это части URI, которые включают динамические значения.
Представьте, что у нас есть REST API для управления товарами, и нам нужно получить товар по его ID. Вот пример URI:
https://api.myapp.com/products/42
Здесь 42 — это идентификатор товара, и мы хотим извлечь его из пути. Для этого используется аннотация @PathVariable.
Аннотация @PathVariable
Spring позволяет "выцарапывать" эти значения из URI следующим образом:
@RestController
@RequestMapping("/products")
public class ProductController {
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
// Логика получения продукта по ID
return productService.getProductById(id);
}
}
Когда клиент отправит запрос GET /products/42, переменная id получит значение 42.
Объединяем @RequestParam и @PathVariable
А теперь, как говорят программисты, идём на уровень выше. Мы можем совмещать их вместе! Например, можно сделать следующую комбинацию:
- URI содержит динамическое значение (
id), чтобы идентифицировать ресурс. - Query Parameters используются для дополнительной настройки.
Пример: получение заказов пользователя с фильтром
@RestController
@RequestMapping("/users")
public class UserController {
@GetMapping("/{userId}/orders")
public List<Order> getUserOrders(
@PathVariable Long userId,
@RequestParam(required = false) String status,
@RequestParam(defaultValue = "date") String sort
) {
// Логика фильтрации заказов пользователя
return orderService.getUserOrders(userId, status, sort);
}
}
Запрос:
GET /users/101/orders?status=completed&sort=price
В этом примере:
userIdбудет равен101.statusбудет равен"completed".sortбудет равен"price".
Валидируем параметры запроса
Не всегда клиенты будут отправлять нам корректные данные. апример, что делать, если в запросе указан ID пользователя как abc, а это явно некорректно?
Обработка ошибок
Spring автоматически вернет ошибку, если @PathVariable или @RequestParam не соответствует ожидаемому типу. Например:
@GetMapping("/{id}")
public Product getProductById(@PathVariable Long id) {
return productService.getProductById(id);
}
Запрос GET /products/abc вызовет:
HTTP 400 Bad Request
Чтобы сделать обработку ошибок более изящной, можно использовать аннотацию @ExceptionHandler:
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public ResponseEntity<String> handleTypeMismatch(MethodArgumentTypeMismatchException ex) {
return ResponseEntity
.badRequest()
.body("Invalid parameter: " + ex.getName());
}
}
Теперь ошибка будет более дружелюбной для клиента:
HTTP 400 Bad Request
Body: Invalid parameter: id
Практика: Пример REST API для работы с книгами
Давайте создадим REST API для работы с книгами. API позволит:
- Получать книгу по ID.
- Искать книги по жанру с сортировкой.
Класс сущности Book
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String title;
private String genre;
private double price;
// Геттеры и сеттеры
}
Репозиторий BookRepository
@Repository
public interface BookRepository extends JpaRepository<Book, Long> {
List<Book> findByGenre(String genre, Sort sort);
}
Сервис BookService
@Service
public class BookService {
@Autowired
private BookRepository bookRepository;
public Book getBookById(Long id) {
return bookRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Book not found!"));
}
public List<Book> getBooksByGenre(String genre, String sortField) {
Sort sort = Sort.by(Sort.Direction.ASC, sortField);
return bookRepository.findByGenre(genre, sort);
}
}
Контроллер BookController
@RestController
@RequestMapping("/books")
public class BookController {
@Autowired
private BookService bookService;
@GetMapping("/{id}")
public Book getBookById(@PathVariable Long id) {
return bookService.getBookById(id);
}
@GetMapping
public List<Book> getBooksByGenre(
@RequestParam(required = false) String genre,
@RequestParam(defaultValue = "title") String sort
) {
return bookService.getBooksByGenre(genre, sort);
}
}
Теперь:
GET /books/1вернет книгу с ID 1.GET /books?genre=fantasy&sort=priceвернет все книги жанра "fantasy", отсортированные по цене.
Типичные ошибки и их решение
@PathVariableотсутствует в URI. Убедитесь, что переменная пути указана в маршруте (например,/{id}).- Неправильный тип данных параметра. Если
idожидаетLong, а клиент передал строку, будет ошибка 400. - Отсутствие обязательных Query Parameters. Убедитесь, что вы используете
required = false, если параметр необязателен.
На этом этапе вы освоили работу с Query Parameters и Path Variables. Теперь ваши REST API станут более функциональными и гибкими. Держите курс на следующее занятие и не забывайте тестировать API!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ