Перейти к основному содержимому

REST API

REST (Representational State Transfer) — архитектурный стиль для создания веб-сервисов.

Основные принципы REST​

1. Client-Server​

Клиент и сервер независимы друг от друга.

2. Stateless​

Каждый запрос содержит всю необходимую информацию. Сервер не хранит состояние клиента.

3. Cacheable​

Ответы могут кэшироваться для улучшения производительности.

4. Uniform Interface​

Единообразный интерфейс взаимодействия.

5. Layered System​

Клиент не знает подключен ли он напрямую к серверу или через прокси.

HTTP методы​

GET — Получение данных​

GET /api/users
GET /api/users/123
GET /api/users?status=active&limit=10

Характеристики:

  • Безопасный (не изменяет данные)
  • Идемпотентный (повторный вызов дает тот же результат)
  • Может кэшироваться

Пример ответа:

{
"id": 123,
"email": "user@example.com",
"name": "Ivan Petrov",
"created_at": "2026-01-15T10:30:00Z"
}

POST — Создание ресурса​

POST /api/users
Content-Type: application/json

{
"email": "newuser@example.com",
"password": "secret123",
"name": "New User"
}

Характеристики:

  • Не безопасный (изменяет данные)
  • Не идемпотентный (повторный вызов создаст дубликат)

Ответ:

HTTP/1.1 201 Created
Location: /api/users/124

{
"id": 124,
"email": "newuser@example.com",
"name": "New User",
"created_at": "2026-04-11T12:00:00Z"
}

PUT — Полное обновление​

PUT /api/users/123
Content-Type: application/json

{
"email": "updated@example.com",
"name": "Updated Name",
"phone": "+79001234567"
}

Характеристики:

  • Не безопасный
  • Идемпотентный (повторный вызов дает тот же результат)
  • Заменяет ресурс полностью

PATCH — Частичное обновление​

PATCH /api/users/123
Content-Type: application/json

{
"name": "New Name"
}

Характеристики:

  • Не безопасный
  • Может быть идемпотентным
  • Обновляет только указанные поля

DELETE — Удаление​

DELETE /api/users/123

Характеристики:

  • Не безопасный
  • Идемпотентный

Ответ:

HTTP/1.1 204 No Content

HTTP статус-коды​

2xx — Успех​

  • 200 OK — запрос выполнен успешно
  • 201 Created — ресурс создан
  • 204 No Content — успех, но нет тела ответа (DELETE)

3xx — Перенаправление​

  • 301 Moved Permanently — ресурс перемещен навсегда
  • 302 Found — временное перенаправление
  • 304 Not Modified — ресурс не изменился (кэш)

4xx — Ошибка клиента​

  • 400 Bad Request — некорректный запрос
  • 401 Unauthorized — требуется аутентификация
  • 403 Forbidden — доступ запрещен
  • 404 Not Found — ресурс не найден
  • 409 Conflict — конфликт (например, email уже существует)
  • 422 Unprocessable Entity — валидация не прошла
  • 429 Too Many Requests — превышен лимит запросов

5xx — Ошибка сервера​

  • 500 Internal Server Error — внутренняя ошибка сервера
  • 502 Bad Gateway — ошибка прокси
  • 503 Service Unavailable — сервис недоступен
  • 504 Gateway Timeout — таймаут прокси

Структура URL​

RESTful URL design​

✅ Хорошо:

GET /api/users # Список пользователей
GET /api/users/123 # Конкретный пользователь
POST /api/users # Создать пользователя
PUT /api/users/123 # Обновить пользователя
DELETE /api/users/123 # Удалить пользователя

GET /api/users/123/orders # Заказы пользователя
GET /api/orders/456/items # Товары в заказе

❌ Плохо:

GET /api/getUsers
GET /api/user?id=123
POST /api/createUser
GET /api/deleteUser?id=123

Правила именования​

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

    • ✅ /users
    • ❌ /getUsers
  2. Множественное число для коллекций

    • ✅ /users
    • ❌ /user
  3. Kebab-case для составных слов

    • ✅ /order-items
    • ❌ /orderItems, /order_items
  4. Вложенность для связей

    • ✅ /users/123/orders
    • ❌ /orders?user_id=123
  5. Версионирование

    • ✅ /api/v1/users
    • ✅ /api/v2/users

Query параметры​

Фильтрация​

GET /api/products?category=electronics&price_min=100&price_max=500

Сортировка​

GET /api/users?sort=created_at&order=desc
GET /api/products?sort=-price # минус = desc

Пагинация​

Offset-based:

GET /api/users?limit=20&offset=40 # страница 3

Page-based:

GET /api/users?page=3&per_page=20

Cursor-based (для больших данных):

GET /api/users?cursor=eyJpZCI6MTIzfQ==&limit=20

Поиск​

GET /api/products?q=laptop
GET /api/users?search=ivan

Выборка полей​

GET /api/users?fields=id,email,name

Аутентификация и авторизация​

Bearer Token (JWT)​

GET /api/users/me
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

API Key​

GET /api/users
X-API-Key: your-api-key-here

Basic Auth​

GET /api/users
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=

Формат ответов​

Успешный ответ​

{
"data": {
"id": 123,
"email": "user@example.com",
"name": "Ivan"
}
}

Список с пагинацией​

{
"data": [
{"id": 1, "name": "User 1"},
{"id": 2, "name": "User 2"}
],
"meta": {
"total": 150,
"page": 1,
"per_page": 20,
"total_pages": 8
},
"links": {
"first": "/api/users?page=1",
"last": "/api/users?page=8",
"prev": null,
"next": "/api/users?page=2"
}
}

Ошибка​

{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": [
{
"field": "email",
"message": "Email is required"
},
{
"field": "password",
"message": "Password must be at least 8 characters"
}
]
}
}

HATEOAS​

Hypermedia As The Engine Of Application State — включение ссылок на связанные ресурсы.

{
"id": 123,
"name": "Ivan",
"email": "ivan@example.com",
"_links": {
"self": {"href": "/api/users/123"},
"orders": {"href": "/api/users/123/orders"},
"avatar": {"href": "/api/users/123/avatar"}
}
}

Идемпотентность​

Идемпотентный запрос — повторное выполнение дает тот же результат.

МетодИдемпотентный?
GET✅ Да
POST❌ Нет
PUT✅ Да
PATCH⚠️ Зависит
DELETE✅ Да

Пример:

# Первый вызов
DELETE /api/users/123 → 204 No Content

# Повторный вызов
DELETE /api/users/123 → 404 Not Found (но это ок!)

Rate Limiting​

Ограничение количества запросов.

Заголовки:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1618308000

Ответ при превышении:

HTTP/1.1 429 Too Many Requests
Retry-After: 3600

{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests. Try again in 1 hour."
}
}

Версионирование API​

В URL (рекомендуется)​

/api/v1/users
/api/v2/users

В заголовке​

GET /api/users
Accept: application/vnd.myapi.v2+json

В query параметре​

/api/users?version=2

Документирование API​

OpenAPI (Swagger)​

openapi: 3.0.0
info:
title: User API
version: 1.0.0

paths:
/users:
get:
summary: Get list of users
parameters:
- name: limit
in: query
schema:
type: integer
default: 20
responses:
'200':
description: Successful response
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/User'

components:
schemas:
User:
type: object
properties:
id:
type: integer
email:
type: string
name:
type: string

Инструменты документирования​

  • Swagger UI — интерактивная документация
  • Postman — коллекции запросов
  • Redoc — красивая документация из OpenAPI
  • API Blueprint — альтернатива OpenAPI

Тестирование API​

Postman​

// Тест статус-кода
pm.test("Status code is 200", function () {
pm.response.to.have.status(200);
});

// Тест структуры ответа
pm.test("Response has user data", function () {
var jsonData = pm.response.json();
pm.expect(jsonData).to.have.property('id');
pm.expect(jsonData).to.have.property('email');
});

// Сохранение переменной
var jsonData = pm.response.json();
pm.environment.set("user_id", jsonData.id);

cURL​

# GET запрос
curl -X GET "https://api.example.com/users/123" \
-H "Authorization: Bearer token"

# POST запрос
curl -X POST "https://api.example.com/users" \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","name":"Test"}'

# С выводом заголовков
curl -i -X GET "https://api.example.com/users"

# Сохранение ответа в файл
curl -X GET "https://api.example.com/users" -o users.json

Best Practices​

1. Используй правильные HTTP методы​

  • GET для чтения
  • POST для создания
  • PUT/PATCH для обновления
  • DELETE для удаления

2. Возвращай правильные статус-коды​

  • 200 для успешного GET/PUT/PATCH
  • 201 для успешного POST
  • 204 для успешного DELETE
  • 400 для ошибок валидации
  • 404 для несуществующих ресурсов

3. Используй существительные в URL​

❌ /getUsers, /createUser ✅ /users

4. Версионируй API​

Всегда включай версию в URL: /api/v1/users

5. Используй пагинацию​

Не возвращай все записи сразу.

6. Фильтруй и сортируй через query параметры​

/users?status=active&sort=created_at

7. Обрабатывай ошибки консистентно​

Единый формат ошибок во всем API.

8. Используй HTTPS​

Всегда шифруй трафик.

9. Документируй API​

OpenAPI/Swagger спецификация обязательна.

10. Логируй запросы​

Для отладки и мониторинга.

Частые ошибки​

1. Использование GET для изменения данных​

❌ GET /api/users/123/delete ✅ DELETE /api/users/123

2. Возврат неправильных статус-кодов​

❌ Возврат 200 при ошибке валидации ✅ Возврат 422 Unprocessable Entity

3. Отсутствие версионирования​

❌ /api/users (что если нужно изменить формат?) ✅ /api/v1/users

4. Игнорирование идемпотентности​

❌ POST для обновления ✅ PUT/PATCH для обновления

5. Слишком много вложенности​

❌ /api/users/123/orders/456/items/789/reviews ✅ /api/reviews/789 или /api/order-items/789/reviews

Примеры реальных API​

GitHub API​

GET https://api.github.com/users/octocat
GET https://api.github.com/repos/owner/repo/issues
POST https://api.github.com/repos/owner/repo/issues

Stripe API​

POST https://api.stripe.com/v1/customers
GET https://api.stripe.com/v1/charges

Twitter API​

GET https://api.twitter.com/2/tweets/:id
POST https://api.twitter.com/2/tweets

Инструменты​

  • Postman — тестирование и документирование
  • Insomnia — альтернатива Postman
  • Swagger Editor — редактор OpenAPI спецификаций
  • HTTPie — CLI клиент (красивее curl)
  • Paw — API клиент для macOS

Полезные ресурсы​