Learnly
Проектирование API/Глава 19/Урок 1

Практика: проектируем API для интернет-магазина

Практика: проектируем API для интернет-магазина

Собираем всё что изучили в курсе в одном реальном примере. Спроектируем REST API для интернет-магазина с нуля, от списка ресурсов до полной таблицы эндпоинтов.


Шаг 1: Определяем ресурсы

Интернет-магазин работает с:

Ресурс Описание
users Покупатели и администраторы
products Товары
categories Категории товаров
cart Корзина пользователя
cart_items Позиции в корзине
orders Заказы
order_items Позиции заказа
addresses Адреса доставки
reviews Отзывы на товары

Шаг 2: Полная таблица эндпоинтов

Аутентификация

Метод URL Описание Доступ
POST /v1/auth/register Регистрация Публичный
POST /v1/auth/login Вход Публичный
POST /v1/auth/logout Выход Авторизован
POST /v1/auth/refresh Обновить токен Авторизован

Пользователи

Метод URL Описание Доступ
GET /v1/users/me Мой профиль Авторизован
PATCH /v1/users/me Обновить профиль Авторизован
GET /v1/users Список пользователей Admin
GET /v1/users/:id Пользователь по ID Admin
DELETE /v1/users/:id Удалить пользователя Admin

Товары

Метод URL Описание Доступ
GET /v1/products Список товаров Публичный
GET /v1/products/:id Товар по ID Публичный
POST /v1/products Создать товар Admin
PATCH /v1/products/:id Обновить товар Admin
DELETE /v1/products/:id Удалить товар Admin
GET /v1/categories/:id/products Товары категории Публичный

Корзина

Метод URL Описание Доступ
GET /v1/cart Моя корзина Авторизован
POST /v1/cart/items Добавить в корзину Авторизован
PATCH /v1/cart/items/:id Изменить количество Авторизован
DELETE /v1/cart/items/:id Удалить из корзины Авторизован
DELETE /v1/cart Очистить корзину Авторизован

Заказы

Метод URL Описание Доступ
POST /v1/orders Оформить заказ Авторизован
GET /v1/orders Мои заказы Авторизован
GET /v1/orders/:id Заказ по ID Авторизован
POST /v1/orders/:id/cancel Отменить заказ Авторизован
GET /v1/admin/orders Все заказы Admin
PATCH /v1/admin/orders/:id/status Изменить статус Admin

Шаг 3: Структуры данных

Товар

GET /v1/products/42

{
  "id": 42,
  "name": "Ноутбук Dell XPS 15",
  "slug": "dell-xps-15",
  "description": "15-дюймовый ноутбук с OLED дисплеем...",
  "price": 149999,
  "currency": "RUB",
  "category": {
    "id": 5,
    "name": "Ноутбуки",
    "slug": "laptops"
  },
  "images": [
    { "url": "https://cdn.example.com/products/42/main.jpg", "is_main": true },
    { "url": "https://cdn.example.com/products/42/side.jpg", "is_main": false }
  ],
  "attributes": {
    "brand": "Dell",
    "processor": "Intel Core i7-12700H",
    "ram_gb": 32,
    "storage_gb": 1000
  },
  "stock": {
    "quantity": 15,
    "in_stock": true
  },
  "rating": {
    "average": 4.7,
    "count": 89
  },
  "created_at": "2024-01-15T09:00:00Z",
  "updated_at": "2024-03-10T14:30:00Z"
}

Список товаров с пагинацией и фильтрами

GET /v1/products?category_id=5&min_price=50000&max_price=200000&in_stock=true&sort=-price&page=1&per_page=24
{
  "data": [
    { "id": 42, "name": "Dell XPS 15", "price": 149999, "image_url": "...", "in_stock": true },
    { "id": 38, "name": "MacBook Pro 14", "price": 199999, "image_url": "...", "in_stock": true }
  ],
  "pagination": {
    "current_page": 1,
    "per_page": 24,
    "total": 47,
    "total_pages": 2,
    "has_next": true,
    "has_prev": false
  },
  "filters_applied": {
    "category_id": 5,
    "min_price": 50000,
    "max_price": 200000,
    "in_stock": true
  }
}

Корзина

GET /v1/cart

{
  "id": "cart_user_123",
  "items": [
    {
      "id": 1,
      "product": {
        "id": 42,
        "name": "Ноутбук Dell XPS 15",
        "price": 149999,
        "image_url": "https://cdn.example.com/products/42/main.jpg"
      },
      "quantity": 1,
      "subtotal": 149999
    },
    {
      "id": 2,
      "product": {
        "id": 17,
        "name": "Мышь Logitech MX Master",
        "price": 8999,
        "image_url": "..."
      },
      "quantity": 2,
      "subtotal": 17998
    }
  ],
  "total": 167997,
  "currency": "RUB",
  "items_count": 3
}

Оформление заказа

POST /v1/orders

{
  "address_id": 5,
  "delivery_method": "courier",
  "payment_method": "card",
  "promo_code": "SAVE10",
  "comment": "Оставьте у двери"
}

Ответ:

HTTP/1.1 201 Created

{
  "id": 1047,
  "number": "ORD-2024-001047",
  "status": "pending",
  "items": [
    {
      "product_id": 42,
      "name": "Ноутбук Dell XPS 15",
      "quantity": 1,
      "price": 149999
    }
  ],
  "delivery": {
    "method": "courier",
    "address": {
      "city": "Москва",
      "street": "ул. Ленина",
      "building": "42",
      "apartment": "15",
      "postal_code": "123456"
    },
    "estimated_date": "2024-03-20"
  },
  "payment": {
    "method": "card",
    "status": "pending",
    "amount": 152997
  },
  "pricing": {
    "subtotal": 167997,
    "discount": 15000,
    "discount_reason": "Промокод SAVE10 (-10%)",
    "delivery_cost": 0,
    "total": 152997
  },
  "created_at": "2024-03-15T10:23:00Z"
}

Шаг 4: Аутентификация и права доступа

Используем JWT с access + refresh токенами:

POST /v1/auth/login
{ "email": "user@example.com", "password": "password123" }

→ 200 OK
{
  "access_token": "eyJhbGci...",
  "refresh_token": "eyJhbGci...",
  "expires_in": 900,
  "user": {
    "id": 123,
    "name": "Иван Петров",
    "role": "customer"
  }
}

Роли: customer (покупатель) и admin.


Шаг 5: Обработка ошибок

// Товар не найден
HTTP/1.1 404 Not Found
{
  "error": {
    "code": "PRODUCT_NOT_FOUND",
    "message": "Товар с id=999 не найден"
  }
}

// Товара нет в наличии
HTTP/1.1 409 Conflict
{
  "error": {
    "code": "OUT_OF_STOCK",
    "message": "Товар недоступен в запрошенном количестве",
    "context": {
      "requested": 5,
      "available": 2
    }
  }
}

// Промокод не работает
HTTP/1.1 422 Unprocessable Entity
{
  "error": {
    "code": "PROMO_CODE_EXPIRED",
    "message": "Срок действия промокода истёк",
    "context": {
      "expired_at": "2024-03-01T00:00:00Z"
    }
  }
}

Итоговый чеклист проекта

  • ✅ Ресурсы в множественном числе, существительные
  • ✅ Версия в URL /v1/
  • ✅ Правильные HTTP методы для каждой операции
  • ✅ Правильные статус-коды (201 при создании, 204 при удалении)
  • ✅ Пагинация для списков
  • ✅ Фильтрация и сортировка через query params
  • ✅ JWT аутентификация с ролями
  • ✅ Понятные коды ошибок с details
  • ✅ Вложенность не глубже 2 уровней
  • ✅ Действия через POST (cancel, activate)

Это полноценный REST API для интернет-магазина который соответствует всем принципам изученным в курсе.

AI-тест
1 / 15

Какие вопросы стоит проработать при проектировании REST API интернет-магазина?