Загрузка...
Загрузка...
Руководство по работе с JSON в REST API: парсинг ответов, валидация структуры, обработка ошибок и рекомендации для фронтенда и бэкенда.
Руководство по типичным ошибкам в JSON: синтаксис, валидация, инструменты поиска и исправления некорректных данных.
Веб-разработкаПодробное руководство по работе с JSON: валидация, форматирование, минификация и обработка ошибок. Практические примеры и лучшие практики для веб-разработчиков.
РазработкаКак конвертировать CSV в JSON и обратно. Форматы данных, разделители, обработка кавычек, практические примеры на JavaScript и Python.
DevOpsJSON Schema: draft-07, 2020-12. Ключевые слова type, properties, required. Примеры валидации пользователя и API-контракта. Ajv, OpenAPI.
Поделитесь с коллегами или изучите другие материалы блога
JSON — основной формат обмена данными в REST API. Корректная работа с JSON на клиенте и сервере включает парсинг, валидацию структуры и обработку ошибок. В этой статье рассмотрены практические приёмы и рекомендации.
const response = await fetch('/api/users');
if (!response.ok) {
throw new Error(`HTTP ${response.status}`);
}
const data = await response.json();
response.json() возвращает Promise и парсит тело ответа. При невалидном JSON будет выброшено исключение.
try {
const data = await response.json();
return data;
} catch (e) {
if (e instanceof SyntaxError) {
console.error('Invalid JSON in response');
}
throw e;
}
Перед вызовом response.json() можно проверить заголовок:
const contentType = response.headers.get('Content-Type');
if (!contentType?.includes('application/json')) {
throw new Error('Expected JSON response');
}
Парсинг проверяет только синтаксис. Структура данных может не соответствовать ожиданиям. Варианты валидации:
function parseUser(data) {
if (!data || typeof data !== 'object') {
throw new Error('Invalid user object');
}
if (typeof data.id !== 'number' || typeof data.name !== 'string') {
throw new Error('Missing or invalid fields');
}
return data;
}
Zod (TypeScript/JavaScript):
import { z } from 'zod';
const UserSchema = z.object({
id: z.number(),
name: z.string(),
email: z.string().email().optional(),
});
const data = UserSchema.parse(jsonData);
При несоответствии схеме parse выбросит ошибку с описанием.
На бэкенде всегда валидируйте входящий JSON:
Content-Type: application/jsonДля больших JSON-ответов рассмотрите:
JSON Formatter на rechecker.ru — валидация и форматирование JSON. Удобно для отладки ответов API.
Некоторые API возвращают 204 No Content или пустое тело при успехе. Вызов response.json() на пустом теле вызовет ошибку. Проверяйте response.ok и наличие тела.
Даты, большие числа — JSON не имеет типов для них. Даты приходят строками (ISO 8601), большие числа могут терять точность в JavaScript. Используйте библиотеки (например, json-bigint) при необходимости.
JSON должен быть в UTF-8. Убедитесь, что сервер отдаёт корректный Content-Type: application/json; charset=utf-8.
Рекомендуемая структура ошибки в JSON:
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid email format",
"details": [
{ "field": "email", "message": "Must be a valid email" }
]
}
}
Единый формат упрощает обработку на клиенте.
Типичные форматы:
{
"data": [...],
"meta": {
"page": 1,
"perPage": 20,
"total": 150
}
}
Или cursor-based:
{
"data": [...],
"nextCursor": "eyJpZCI6MjF9"
}
Типичные синтаксические ошибки и их исправление — в Ошибки JSON: как найти и исправить некорректный JSON. Общее руководство по валидации — в JSON валидация и форматирование.
Для больших ответов можно использовать потоковое чтение:
const response = await fetch('/api/stream');
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
// Обработка полных JSON-объектов из buffer (NDJSON)
}
Клиент может запрашивать JSON через заголовок Accept:
Accept: application/json
Сервер может вернуть другой формат (XML, HTML) при отсутствии Accept или указании других типов. Всегда проверяйте Content-Type ответа.
Ограничивайте размер входящего JSON на сервере. В Express: express.json({ limit: '1mb' }). Большие payload могут использоваться для DoS-атак.
Избегайте eval() для парсинга JSON — это выполнение кода. Используйте только JSON.parse(). При десериализации из ненадёжных источников проверяйте структуру на наличие неожиданных полей (prototype pollution).
При отладке API-запросов в DevTools (Network) можно просматривать ответ в формате JSON. Для копирования и форматирования используйте JSON Formatter.
При временных сбоях (503, таймауты) реализуйте retry с экспоненциальной задержкой:
async function fetchWithRetry(url, options = {}, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
const res = await fetch(url, options);
if (res.ok) return res;
if (res.status >= 500 && i < maxRetries - 1) {
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
continue;
}
return res;
} catch (e) {
if (i === maxRetries - 1) throw e;
await new Promise(r => setTimeout(r, Math.pow(2, i) * 1000));
}
}
}
Для редко меняющихся данных кэшируйте JSON в памяти или localStorage. Учитывайте заголовки Cache-Control, ETag для HTTP-кэширования.
При работе с API в TypeScript определяйте интерфейсы для ответов:
interface UserResponse {
id: number;
name: string;
email?: string;
}
const data: UserResponse = await response.json();
Это не заменяет runtime-валидацию, но улучшает автодополнение и отлов ошибок на этапе компиляции.