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
Правила именования
-
Используй существительные, не глаголы
- ✅
/users - ❌
/getUsers
- ✅
-
Множественное число для коллекций
- ✅
/users - ❌
/user
- ✅
-
Kebab-case для составных слов
- ✅
/order-items - ❌
/orderItems,/order_items
- ✅
-
Вложенность для связей
- ✅
/users/123/orders - ❌
/orders?user_id=123
- ✅
-
Версионирование
- ✅
/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
Полезные ресурсы
- REST API Tutorial
- HTTP Status Codes
- OpenAPI Specification
- Книга "RESTful Web APIs" — Leonard Richardson
- API Design Guide от Google