JSON в Node.js: Полное руководство по обработке данных
JSON (JavaScript Object Notation) — это легковесный формат обмена данными, который стал стандартом де-факто для веб-API, конфигурационных файлов и хранения структурированной информации. В среде Node.js работа с JSON является неотъемлемой частью практически любого приложения. В этой статье мы подробно рассмотрим все аспекты обработки JSON: от базового парсинга до продвинутой потоковой обработки.
1. Основы: Парсинг и сериализация
В Node.js для работы с JSON используются два глобальных метода: JSON.parse() и JSON.stringify(). Они доступны без подключения дополнительных модулей.
JSON.parse() — Преобразование строки в объект
Метод JSON.parse() принимает строку JSON и возвращает соответствующий JavaScript-объект. Важно, что строка должна быть строго валидным JSON.
const jsonString = '{"name": "Alice", "age": 30, "isAdmin": false}';
const user = JSON.parse(jsonString);
console.log(user.name); // Alice
console.log(typeof user); // object
Метод также поддерживает второй аргумент — функцию "reviver", которая позволяет трансформировать значения в процессе парсинга:
const data = '{"date": "2025-01-15T10:00:00Z"}';
const parsed = JSON.parse(data, (key, value) => {
if (key === 'date') return new Date(value);
return value;
});
console.log(parsed.date instanceof Date); // true
JSON.stringify() — Преобразование объекта в строку
Метод JSON.stringify() делает обратное преобразование — превращает JavaScript-объект в JSON-строку.
const user = {
name: 'Bob',
age: 25,
hobbies: ['coding', 'reading']
};
const json = JSON.stringify(user);
console.log(json);
// {"name":"Bob","age":25,"hobbies":["coding","reading"]}
Метод принимает три аргумента: значение, заменяющую функцию (replacer) и количество пробелов для форматирования (space):
const obj = { a: 1, b: 2, c: 3 };
// Форматированный вывод с отступами
console.log(JSON.stringify(obj, null, 2));
// {
// "a": 1,
// "b": 2,
// "c": 3
// }
// Фильтрация ключей с помощью replacer
const filtered = JSON.stringify(obj, ['a', 'c'], 2);
console.log(filtered);
// {
// "a": 1,
// "c": 3
// }
2. Чтение и запись JSON-файлов
В реальных приложениях JSON-данные часто хранятся в файлах. Для работы с файловой системой используется встроенный модуль fs.
Синхронное чтение и запись
const fs = require('fs');
const path = require('path');
const filePath = path.join(__dirname, 'config.json');
// Чтение
const rawData = fs.readFileSync(filePath, 'utf-8');
const config = JSON.parse(rawData);
console.log(config.port);
// Запись
const newConfig = { port: 3000, host: 'localhost' };
fs.writeFileSync(filePath, JSON.stringify(newConfig, null, 2));
Асинхронное чтение и запись (рекомендуемый способ)
const fs = require('fs').promises;
async function readConfig() {
try {
const data = await fs.readFile('config.json', 'utf-8');
return JSON.parse(data);
} catch (err) {
console.error('Ошибка чтения файла:', err);
throw err;
}
}
async function writeConfig(config) {
await fs.writeFile('config.json', JSON.stringify(config, null, 2));
}
// Использование
(async () => {
const config = await readConfig();
config.port = 4000;
await writeConfig(config);
})();
3. Валидация JSON
Иногда необходимо проверить, является ли строка валидным JSON, не вызывая исключение. Самый надежный способ — обернуть JSON.parse() в try-catch:
function isValidJSON(str) {
try {
JSON.parse(str);
return true;
} catch (e) {
return false;
}
}
console.log(isValidJSON('{"key": "value"}')); // true
console.log(isValidJSON('{invalid}')); // false
Для более сложной валидации структуры данных используйте библиотеки вроде ajv (Another JSON Schema Validator):
const Ajv = require('ajv');
const ajv = new Ajv();
const schema = {
type: 'object',
properties: {
name: { type: 'string', minLength: 1 },
age: { type: 'number', minimum: 0, maximum: 150 },
email: { type: 'string', format: 'email' }
},