Использование JSON в REST API: лучшие практики
JSON в REST API
JSON и REST API — идеальное сочетание. Лёгкий синтаксис JSON, встроенная поддержка массивов и универсальная языковая поддержка делают его форматом по умолчанию для современных веб-API. Но простого использования JSON в вашем API недостаточно — следование устоявшимся соглашениям и лучшим практикам гарантирует, что ваш API будет согласованным, интуитивно понятным и лёгким в интеграции.
Формат запросов и ответов
Единая структура конверта
Примите единый JSON-конверт для всех ответов API. Это делает обработку на стороне клиента предсказуемой и упрощает обработку ошибок.
{
"status": "success",
"data": {
"user": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
}
},
"meta": {
"requestId": "req-a1b2c3d4",
"timestamp": "2026-07-19T10:30:00Z"
}
}
Snake Case против Camel Case
Выберите одно соглашение об именовании и придерживайтесь его во всём API:
- Camel Case (
createdAt,firstName): распространён в экосистемах JavaScript/TypeScript - Snake Case (
created_at,first_name): распространён в экосистемах Python, Ruby и PHP
Какой бы вариант вы ни выбрали, чётко задокументируйте его и рассмотрите использование слоя трансформации, если ваш бэкенд-язык использует другое соглашение.
HTTP-коды состояния с JSON
Правильные HTTP-коды состояния дополняют ваши JSON-ответы. Используйте их согласованно:
| Код состояния | Значение | Когда использовать |
|-------------|---------|-------------|
| 200 OK | Успех | Успех GET, PUT, PATCH |
| 201 Created | Ресурс создан | Успех POST |
| 204 No Content | Успешное удаление | Успех DELETE (без тела JSON) |
| 400 Bad Request | Недопустимый синтаксис JSON | Некорректное тело запроса |
| 401 Unauthorized | Требуется аутентификация | Отсутствующий или недействительный токен |
| 403 Forbidden | Недостаточно прав | Действительная аутентификация, но нет доступа |
| 404 Not Found | Ресурс не существует | Недействительный ID или путь |
| 422 Unprocessable Entity | Ошибка валидации | Семантические ошибки в корректном JSON |
| 429 Too Many Requests | Превышен лимит запросов | Клиент превышает лимиты |
| 500 Internal Server Error | Сбой на стороне сервера | Непредвиденные ошибки |
Стандартный формат ответа об ошибке
{
"status": "error",
"error": {
"code": "VALIDATION_ERROR",
"message": "Тело запроса содержит недопустимые поля",
"details": [
{
"field": "email",
"message": "Должен быть действительным адресом email",
"code": "INVALID_FORMAT"
},
{
"field": "age",
"message": "Должно быть положительным целым числом",
"code": "OUT_OF_RANGE"
}
]
}
}
Вложенные ресурсы
Представление связей
REST API часто требуется представлять связанные ресурсы. Вот распространённые шаблоны:
Встроенный (жадная загрузка):
{
"order": {
"id": 5001,
"total": 29.99,
"customer": {
"id": 123,
"name": "Alice",
"email": "alice@example.com"
},
"items": [
{
"productId": 42,
"name": "Widget",
"quantity": 2,
"price": 14.99
}
]
}
}
Ссылочный (ленивая загрузка) — используйте ID и предоставляйте отдельные эндпоинты:
{
"order": {
"id": 5001,
"total": 29.99,
"customerId": 123,
"itemIds": [101, 102]
}
}
Практическое правило: встраивайте связанные данные, которые всегда нужны вместе. Ссылайтесь на данные, которые извлекаются условно или в другое время.
Шаблоны пагинации
При возврате списков ресурсов пагинация необходима. Используйте единый формат пагинации:
Пагинация на основе смещения
{
"status": "success",
"data": [
{ "id": 1, "name": "User 1" },
{ "id": 2, "name": "User 2" }
],
"pagination": {
"page": 1,
"perPage": 20,
"totalItems": 156,
"totalPages": 8,
"links": {
"first": "/api/users?page=1&perPage=20",
"prev": null,
"next": "/api/users?page=2&perPage=20",
"last": "/api/users?page=8&perPage=20"
}
}
}
Пагинация на основе курсора (рекомендуется для больших наборов данных)
{
"status": "success",
"data": [
{ "id": 100, "name": "User 100" },
{ "id": 101, "name": "User 101" }
],
"pagination": {
"nextCursor": "eyJpZCI6MTAxfQ==",
"hasMore": true
}
}
Пагинация на основе курсора более надёжна для данных в реальном времени, где новые записи могут смещать границы страниц.
JSON в запросах API
Тела запросов POST / PUT
Принимайте JSON с заголовком Content-Type: application/json:
{
"title": "Новая запись в блоге",
"content": "Это содержимое...",
"tags": ["json", "rest-api"],
"published": false
}
Частичные обновления с PATCH
Используйте PATCH для частичных обновлений. Принимайте только те поля, которые должны измениться:
// PATCH /api/users/123
{
"email": "newemail@example.com"
}
Фильтрация, сортировка и поиск
Используйте параметры запроса для манипуляции данными, сохраняя тело JSON чистым:
GET /api/users?filter[role]=admin&sort=-createdAt&search=alice
{
"status": "success",
"data": [ /* отфильтрованные, отсортированные результаты */ ]
}
Ограничение частоты запросов
Включайте информацию о лимитах запросов в заголовки ответа и, опционально, в тело JSON:
{
"status": "error",
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Слишком много запросов. Пожалуйста, повторите попытку позже."
},
"meta": {
"rateLimit": {
"limit": 100,
"remaining": 0,
"resetAt": "2026-07-19T11:00:00Z"
}
}
}
Чек-лист лучших практик JSON
- [ ] Используйте согласованное именование ключей (camelCase или snake_case во всём)
- [ ] Возвращайте соответствующие HTTP-коды состояния с каждым ответом
- [ ] Включите единый формат ошибок с машиночитаемыми кодами ошибок
- [ ] Пагинируйте эндпоинты списков со стандартизированным объектом пагинации
- [ ] Используйте JSON Schema для документирования и проверки структур запросов/ответов
- [ ] Устанавливайте
Content-Type: application/jsonна всех JSON-эндпоинтах - [ ] Сжимайте JSON-ответы с помощью gzip или brotli в продакшене
- [ ] Обеспечьте максимальные лимиты размера полезной нагрузки (например, 1 МБ по умолчанию)
- [ ] Используйте HTTPS для шифрования данных JSON при передаче
- [ ] Структурируйте детали ошибок так, чтобы помочь клиентам в отладке, не раскрывая внутренние детали
Проверка JSON вашего API
Пропускайте ответы вашего API через JSON валидатор, чтобы обнаружить ошибки форматирования до того, как они достигнут клиентов. Согласованные, корректные JSON-ответы делают ваш API надёжным и удобным для разработчиков. Используйте наш инструмент JSON Formatter & Validator, чтобы тестировать ваши полезные нагрузки во время разработки.