JSON — это один из самых популярных форматов обмена данными между бекэндом и фронтэндом. Еще JSON известен как JavaScript Object Notation. Он очень похож на то, как выглядят обычные JavaScript объекты, но также имеет свои особенности. Читается - “джейсон”, хотя часть твоих будущих коллег будут говорить и “джсон”, и “жсон”, и даже “жисон”.
JSON не накладывает никаких ограничений на язык программирования, который будет с ним работать. Ты можешь работать в организации, где часть бекэнд сервисов написана на Python, часть на Java, а фронт на JS и все они прекрасно обмениваются JSON сообщениями.
Хранение данных в формате JSON
Начнем с того, что JSON
- это строка. Это позволяет при необходимости очень эффективно сжимать данные. Недостаток — мы не можем хранить циклические структуры данных, например объект, который ссылается на самого себя.
(Почти) все должно быть обернуто в кавычки
В отличие от JavaScript, ты должен пользоваться только двойными кавычками и оборачивать в них все свойства объектов. Одинарные или обратные (косые) кавычки использовать нельзя.
В JS у нас был такой объект
{
name: 'Jack',
isMarried: false,
age: 25,
}
А в JSON он станет таким
{
"name": "Jack",
"isMarried": false,
"age": 25
}
Обрати внимание, что в JavaScript объектах наличие запятой после age: 25,
является допустимым, а в JSON - нет.
Названия всех полей обернуты в двойные кавычки, а значения — не все. Числа и булевы значения хранятся без кавычек.
Объекты хранятся в фигурных скобках
Для хранения объектов используются фигурные скобки, как и в JS.
Заметь, что если сервер отвечает в формате JSON, то предполагается, что он ответит объектом. Ты не можешь просто список полей. Они все обязательно должны быть обернуты в фигурные скобки, чтобы стать JSON объектом.
Массивы хранятся в квадратных скобках
Все точно как в JS, оборачиваем название массива в двойные кавычки, а сам массив указываем в квадратных скобках.
{
"pets": ["Rex", "Sandy"]
}
Еще раз обращаем внимание, что в конце строки нет ни запятой, ни точки с запятой.
Все данные JSON в объекте хранятся как пары “ключ”:“значение”
Как и в JS, ты можешь добавлять в объект только пары ключ:значение
. Если тебе нужно сохранить несколько значений без ключей, то тебе нужен массив.
Конвертация JavaScript объектов в JSON и обратно
Для конвертации из обычного JS объекта в JSON строку, тебе нужна функция JSON.stringify(obj)
. Она доступна без установки дополнительных модулей. Передаешь ей объект obj
и на выходе получаешь JSON объект.
const user = {
name: 'Jack',
isMarried: false,
age: 25,
}
const userJSON = JSON.stringify(user);
console.log(userJSON); // {"name":"Jack","isMarried":false,"age":25}
Для конвертации из JSON в обычный объект, нам нужна функция JSON.parse(s)
. Даем строку в формате JSON на вход, получаем JS объект на выходе.
const jsonString = '{"name":"Jack","isMarried":false,"age":25}';
const parsedUser = JSON.parse(jsonString);
console.log(parsedUser); // { name: 'Jack', isMarried: false, age: 25 }
Express.js и JSON
Так как мы знаем, что JSON объект — это строка, нам будет просто модифицировать сервер и вместо Hello, Express.js
отправлять какой-нибудь объект.
Представим, что нам нужно передать на фронтэнд объект
{
name: 'Hero',
isLearning: true,
level: 'apprentice',
}
Сделаем это несколькими способами. Во всех случаях фронтэнд получит одно и то же, в чем ты можешь убедиться с помощью запроса в браузере.
-
Обычная строка:
server.get('/', (req, res) => { return res.send('{"name":"Hero","isLearning":true,"level":"apprentice"}'); })
-
Объект, преобразованный с помощью
JSON.stringify
:server.get('/', (req, res) => { const user = { name: 'Hero', isLearning: true, level: 'apprentice' }; return res.send(JSON.stringify(user)); })
-
Объект преобразованный с помощью
res.json
:server.get('/', (req, res) => { const user = { name: 'Hero', isLearning: true, level: 'apprentice' }; return res.json(user); })
Повторю еще раз. Во всех случаях в итоге получится одно и то же. Мы отправим ответ со статусом 200 и строкой {"name":"Hero","isLearning":true,"level":"apprentice"}
, которую получатель сможет использовать как ему захочется.
По правде говоря, между res.send
и res.json
есть разница и она состоит в типе ответа. Это специальный заголовок Content-Type, который в случае res.send
устанавливается равным text/html
, а для res.json
— application/json
.
Используй
res.json
, если у тебя есть готовый объект, который ты хочешь отправить в формате JSON.
Третий пример самый удачный, так как нам нужно делать миниум лишних действий. Мы передаем объект в res.json
и преобразование в JSON строку происходит внутри. Дополнительный (явный) вызов JSON.stringify
, как в примере 2, в этом случае не нужен.