JavaRush /Курсы /Модуль 5. Spring /Как правильно верстать URI и работать с ресурсами

Как правильно верстать URI и работать с ресурсами

Модуль 5. Spring
8 уровень , 6 лекция
Открыта

URI (Uniform Resource Identifier) служат ключевым интерфейсом между вашим API и его пользователями. Представьте, что URI — это адреса на карте, которые пользователи (имея в руках навигатор) будут использовать для доступа к функциям вашего приложения. Если ваш URI будет запутанным, несогласованным и непродуманным, пользователи API будут испытывать ту же боль, что и мы, когда едем через весь город, чтобы узнать, что адрес ведёт в никуда.

Чётко спроектированные URI:

  • Улучшают читаемость и предсказуемость API.
  • Обеспечивают единообразие и упрощают поддержку.
  • Помогают новому разработчику быстрее понять структуру API.
  • Способствуют масштабируемости системы в будущем.

Основные правила создания URI

Мы уже с этим разбирались, но стоит повторить. Так что запомните, как мантру: "URI должны быть интуитивно понятными и описывать ресурс, а не действие". Вот что это значит:

1. Используйте существительные вместо глаголов

URI должны представлять собой ресурс, а не действия над ним. Например:

  • Правильно: /users (описывает ресурс "пользователи").
  • Неправильно: /getAllUsers (описывает действие).

Пример:


GET /users       -> Получить список всех пользователей.
GET /users/{id}  -> Получить данные конкретного пользователя.
POST /users      -> Создать нового пользователя.

Такой подход делает API предсказуемым. Вероятность того, что разработчик промахнётся и введёт неправильный URI, сильно снижается.


2. Используйте множественное число для коллекций

Когда вы разрабатываете маршруты для коллекций, такие как список пользователей или список продуктов, используйте множественное число. Это общепринятое соглашение в REST API.

Пример:


/products        -> Список всех продуктов.
/products/{id}   -> Конкретный продукт по ID.

Почему это важно? Потому что так сразу понятно, что /products — это группа, а /products/{id} — конкретный представитель этой группы.

3. Используйте вложенность для логической иерархии

Если ваши ресурсы имеют зависимость или вложенность, это можно выразить через структуру URI. Например, заказы пользователя можно представлять так:


GET /users/{userId}/orders       -> Получить все заказы пользователя.
/users/{userId}/orders/{orderId} -> Получить конкретный заказ для пользователя.

Вложенная структура URI помогает показать связь между двумя ресурсами. Например, "заказ" без пользователя может быть непонятен, но внутри /users/{userId} он сразу находит смысл.

4. Консистентность и читаемость

Часто в проектах встречаются URI вроде этого:


/api/v1/get_all_users

Ну такое... Здесь нарушается всё:

  • Использование нижнего подчёркивания вместо дефиса.
  • Указаны действия вместо ресурсов (get_all_users).
  • Следование неявным соглашениям по написанию.

Хорошо оформленный URI:


/api/v1/users
  • Дефисы для разделений слов (-), а не подчеркивания (_).
  • Минимализм: пишем только то, что важно.

Дефисы в URI лучше воспринимаются и считаются более читабельными.


Работа с версиями API

Версионность — важный аспект гибкого API. Она позволяет вашему API эволюционировать без поломки старых клиентов. Обычно версии включаются в URI.

Способы версионирования:

  1. Версия в пути:
    
    /api/v1/users
    
    Простой, стандартный подход. Удобно для REST API.
  2. Версия в заголовке: Указываете версию через заголовок HTTP:
    
    GET /users
    Content-Type: application/json
    API-Version: 1
    
  3. Версия в параметре запроса:
    
    /users?apiVersion=1
    

Для простоты мы чаще всего будем использовать версию в пути.


Вложенность и структурированность

Вложенные URI используются для представления связей между ресурсами. Но важно помнить, что избыточная вложенность усложняет поддержку. Вложенность более трёх уровней уже считается признаком плохой архитектуры.

Хороший пример:


/users/{userId}/orders/{orderId}

Плохой пример:


/companies/{companyId}/departments/{departmentId}/teams/{teamId}/users/{userId}

Если у вас появляется такая глубокая структура, возможно, стоит пересмотреть модель данных. Например, добавить отдельный сервис для управления "пользователями".


Где использовать Query Parameters?

Query Parameters (параметры запроса) удобны, если вы хотите отфильтровать, отсортировать или уточнить данные. Например:


GET /products?category=electronics&sort=price_asc&page=2

Распределение обязанностей:

  1. URI используют для идентификации ресурсов.
  2. Query Parameters — для поиска, сортировки или ограничения.

Пример: внедряем на практике

Давайте применим всё, чему научились, и создадим REST API для работы с ресурсами "Пользователи" и "Заказы".

REST-контроллер для пользователей


@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    // Получить всех пользователей
    @GetMapping
    public List<User> getAllUsers() {
        return userService.getAllUsers();
    }

    // Получить одного пользователя
    @GetMapping("/{userId}")
    public User getUserById(@PathVariable Long userId) {
        return userService.getUserById(userId);
    }

    // Создать пользователя
    @PostMapping
    public User createUser(@RequestBody User newUser) {
        return userService.createUser(newUser);
    }

    // Обновить пользователя
    @PutMapping("/{userId}")
    public User updateUser(@PathVariable Long userId, @RequestBody User updatedUser) {
        return userService.updateUser(userId, updatedUser);
    }

    // Удалить пользователя
    @DeleteMapping("/{userId}")
    public void deleteUser(@PathVariable Long userId) {
        userService.deleteUser(userId);
    }
}

Обработка вложенности для заказов


@RestController
@RequestMapping("/api/v1/users/{userId}/orders")
public class OrderController {

    // Получить все заказы пользователя
    @GetMapping
    public List<Order> getAllOrdersForUser(@PathVariable Long userId) {
        return orderService.getOrdersByUserId(userId);
    }

    // Получить конкретный заказ
    @GetMapping("/{orderId}")
    public Order getOrderById(@PathVariable Long userId, @PathVariable Long orderId) {
        return orderService.getOrderById(userId, orderId);
    }

    // Создать заказ
    @PostMapping
    public Order createOrder(@PathVariable Long userId, @RequestBody Order newOrder) {
        return orderService.createOrderForUser(userId, newOrder);
    }
}

Пример запросов:

  1. Получить всех пользователей:
    
    GET /api/v1/users
    
  2. Создать нового пользователя:
    
    POST /api/v1/users
    {
        "name": "John Doe",
        "email": "john.doe@example.com"
    }
    
  3. Получить все заказы пользователя:
    
    GET /api/v1/users/1/orders
    
  4. Добавить заказ пользователю:
    
    POST /api/v1/users/1/orders
    {
        "product": "Laptop",
        "quantity": 1
    }
    

Теперь в вашем REST API царит порядок и красота. Продуманный дизайн URI — залог удобства и долговечности вашего API!

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ