Спецификация JSEND
- ·
-
Что это такое? — Простыми словами, JSend — это спецификация, которая определяет некоторые правила форматирования JSON-ответов от веб-серверов. JSend сосредоточена на сообщениях на уровне приложения (в отличие от протокольных или транспортных уровней), что делает ее идеальной для использования в REST-приложениях и API.
Почему? — Существует множество веб-сервисов, которые предоставляют JSON-данные, и у каждого из них свой способ форматирования ответов. Кроме того, разработчики, пишущие для фронтэнд-приложений на JavaScript, постоянно изобретают велосипед для обмена данными с их серверами. Хотя существует много общих шаблонов для структурирования этих данных, нет единой системы для именования или типов ответов. Кроме того, это способствует счастью и единству между разработчиками бэкэнда и дизайнерами фронтэнда, так как каждый может ожидать общего подхода к взаимодействию друг с другом.
Подождите, а разве уже нет спецификаций для этого типа вещей? — Что ж, нет. Несмотря на то, что есть несколько удобных спецификаций для работы с данными в формате JSON, в основном, наиболее заметным является предложение Douglas Crockford по JSONRequest, нет ничего, что бы решало проблемы общих сообщений на уровне приложений. Больше об этом позже.
(Почему) мне это важно? — Если вы разработчик библиотек или фреймворков, то это дает вам консистентный формат, с которым ваши пользователи, скорее всего, уже знакомы, что означает, что они уже будут знать, как потреблять и взаимодействовать с вашим кодом. Если вы веб-разработчик, вам не придется думать о том, как организовать JSON-данные в вашем приложении, и у вас уже будут готовые реализации для быстрого запуска.
Как это работает?
Простой ответ, соответствующий JSend, выглядит следующим образом:
{
status : "success",
data : {
"post" : { "id" : 1, "title" : "A blog post", "body" : "Some useful content" }
}
}
При настройке JSON API у вас будет множество различных типов вызовов и ответов. JSend разделяет ответы на несколько основных типов и определяет обязательные и необязательные ключи для каждого типа:
Тип | Описание | Обязательные ключи | Опциональные ключи |
success | Все прошло хорошо, и (обычно) были возвращены некоторые данные. | status, data | |
fail | Произошла ошибка при отправке данных или не было выполнено какое-то предусловие вызова API. | status, data | |
error | Ошибка произошла при обработке запроса, то есть возникло исключение. | status, message | code, data |
Типы ответов (примеры)
Success
Когда API-запрос успешен, объект JSend используется в качестве простой оболочки для результатов, используя ключ data, как в следующем примере:
GET /posts.json
{
status : "success",
data : {
"posts" : [
{ "id" : 1, "title" : "A blog post", "body" : "Some useful content" },
{ "id" : 2, "title" : "Another blog post", "body" : "More content" },
]
}
}
GET /posts/2.json
{
status : "success",
data : { "post" : { "id" : 2, "title" : "Another blog post", "body" : "More content" }}
}
DELETE /posts/2.json
{
status : "success",
data : null
}
Обязательные ключи:
- status: всегда должен быть установлен на «success«.
- data: служит оберткой для любых данных, возвращаемых вызовом API. Если вызов не возвращает данных (как в последнем примере), data должен быть установлен в null.
Fail
Когда вызов API отклонен из-за неверных данных или условий вызова, ключ data объекта JSend содержит объект, объясняющий, что пошло не так, обычно хеш проверочных ошибок. Например:
POST /posts.json (с телом запроса: «Попытка создать пост в блоге»)
{
status : "fail",
data : { "title" : "A title is required" }
}
Обязательные ключи:
- status должен всегда быть установлен в «fail«.
- data: снова обеспечивает обертку для деталей того, почему запрос не удался. Если причины сбоя соответствуют значениям POST, ключи объекта ответа ДОЛЖНЫ соответствовать этим значениям POST.
Error
Когда вызов API не удался из-за ошибки на сервере. Например:
GET /posts.json
{
status : "error",
message : "Unable to communicate with database"
}
Обязательные ключи:
- status: Всегда должен быть установлен на «error«.
- message: содержит значимое сообщение, читабельное для конечного пользователя (или по крайней мере достойное логирования), объясняющее, что пошло не так.
Опциональные ключи:
- code: числовой код, соответствующий ошибке, если таковая имеется.
- data: Общий контейнер для любой другой информации об ошибке, например, условия, вызвавшие ошибку, трассировки стека и т.д.
Внутри HTTP?
Но вы спрашиваете, не предоставляет ли HTTP уже способ для передачи статуса ответа? Да, дорогой читатель, это так. Так как связано указание статуса ответа в теле сообщения с контекстом HTTP? Два момента:
- Официальная спецификация HTTP содержит более 41 кода состояния, и есть много интерпретаций того, как использовать каждый из них. JSend, с другой стороны, определяет более ограниченный набор кодов состояния, специально связанных с обработкой трафика JSON в контексте динамического веб-интерфейса.
- Спецификация должна быть как можно более маленькой, ограниченной и общеприменимой. Поэтому она должна быть отчасти самодостаточной. Частой практикой при реализации JSON-сервисов является загрузка JavaScript-файла, который передает блок JSON в заданный пользователем обратный вызов. Обработка JSON через XHR во многих JavaScript-фреймворках следует аналогичным образом. Таким образом, конечный пользователь (разработчик) никогда не имеет возможности получить доступ к самому HTTP-ответу.
Итак, к чему это нас приводит? Учёт недостатков существующего положения не отменяет полезность соблюдения стандартов HTTP. Поэтому рекомендуется, чтобы разработчики на стороне сервера использовали оба подхода: предоставляли тело ответа в формате JSend и любые заголовки HTTP, которые наиболее подходят для соответствующего тела ответа.