Стандартный формат ответа JSON API?
Существуют ли стандарты или передовая практика для структурирования ответов JSON от API? Очевидно, что данные каждого приложения отличаются друг от друга, поэтому меня не интересует, а скорее «шаблон отзыва», если хотите. Пример того, что я имею в виду:
Успешный запрос:
{ "success": true, "payload": { /* Application-specific data would go here. */ } }
Ошибка запроса:
- Как параметры отправляются в HTTP-запрос POST?
- iPhone XMLRequest
- Регистрация необработанного HTTP-запроса / ответа в ASP.NET MVC и IIS7
- Почему браузер не может отправлять запрос gzip?
- Где можно найти настройки таймаута по умолчанию для всех браузеров?
{ "success": false, "payload": { /* Application-specific data would go here. */ }, "error": { "code": 123, "message": "An error occurred!" } }
- Допустимо ли иметь более одного знака вопроса в URL-адресе?
- Как использовать параметры, объекты запроса и сеанса, присутствующие в ActionContext?
- HTTP GET в VBS
- Angular 4.3.3 HttpClient: как получить значение из заголовка ответа?
- Отобразить изображение PNG в ответ на запрос JQuery AJAX
- Запросить модуль, как правильно получить ударные символы?
- Получить текущий URL-адрес UIWebView
- Могу ли я загружать внешние таблицы стилей по запросу?
Да, есть несколько стандартов (хотя некоторые свободы по определению стандарта), которые появились:
- API JSON – API JSON охватывает также создание и обновление ресурсов, а не только ответы.
- JSend – Простой и, вероятно, то, что вы уже делаете.
- Протокол OData JSON – очень сложный.
- HAL – как OData, но для того, чтобы быть HATEOAS .
Существуют также форматы описания JSON API:
- развязность
- JSON Schema (используется чванством, но вы можете использовать его отдельно)
- WADL в JSON
- RAML
- HAL, потому что HATEOAS в теории самоописано.
Руководство Google JSON
data
возврата ответа на успех
{ "data": { "id": 1001, "name": "Wing" } }
Ошибка возврата ответа error
{ "error": { "code": 404, "message": "ID not found" } }
и если ваш клиент JS, вы можете использовать if ("error" in response) {}
чтобы проверить, есть ли ошибка.
Я думаю, что стандарт defacto действительно не появился (и, возможно, никогда). Но независимо от того, вот мой прием:
Успешный запрос:
{ "status": "success", "data": { /* Application-specific data would go here. */ }, "message": null /* Or optional success message */ }
Ошибка запроса:
{ "status": "error", "data": null, /* or optional error payload */ "message": "Error xyz has occurred" }
Преимущество: те же элементы верхнего уровня как в случае успеха, так и в случае ошибок
Недостаток: нет кода ошибки, но если вы хотите, вы можете либо изменить статус как код (успех или неудачу), либо вы можете добавить еще один элемент верхнего уровня с именем «код».
Предполагая, что вы задаете вопрос о дизайне веб-сервисов REST и точнее о успехе / ошибке.
Я думаю, что существует 3 разных типа дизайна.
-
Используйте только код состояния HTTP, чтобы указать, была ли ошибка, и попытайтесь ограничить себя стандартными (обычно этого должно быть достаточно).
- Плюсы: Это стандарт, независимый от вашего api.
- Минусы: меньше информации о том, что на самом деле произошло.
-
Используйте HTTP Status + json body (даже если это ошибка). Определите единую структуру для ошибок (например, код, сообщение, причину, тип и т. Д.) И используйте ее для ошибок, если это будет успешным, тогда просто верните ожидаемый ответ json.
- Плюсы: по-прежнему стандарт, когда вы используете существующие коды состояния HTTP, и вы возвращаете json, описывающий ошибку (вы предоставляете больше информации о том, что произошло).
- Минусы: выход json будет меняться в зависимости от ошибки или успеха.
-
Забудьте о статусе http (например: всегда статус 200), всегда используйте json и добавьте в корневой ответ ответ булевский ответ Valid и объект ошибки (код, сообщение и т. Д.), Который будет заполнен, если это ошибка, иначе другие поля (успех).
-
Плюсы: клиент имеет дело только с телом ответа, который является json-строкой и игнорирует статус (?).
-
Минусы: чем меньше стандарт.
-
Это зависит от вас, чтобы выбрать 🙂
В зависимости от API я бы выбрал 2 или 3 (я предпочитаю 2 для json rest apis). Еще одна вещь, которую я испытал при разработке REST Api, – это важность документации для каждого ресурса (url): параметры, тело, ответ, заголовки и т. Д. + Примеры.
Я также рекомендовал бы использовать jersey (jax-rs implementation) + genson (java / json databinding library). Вам просто нужно сбросить genson + jersey в ваш путь к classам, и json автоматически поддерживается.
РЕДАКТИРОВАТЬ:
-
Решение 2 сложнее всего реализовать, но преимущество состоит в том, что вы можете прекрасно справляться с исключениями, а не только с бизнес-ошибками, первоначальные усилия важнее, но вы выигрываете в долгосрочной перспективе.
-
Решение 3 легко реализовать как на стороне сервера, так и на стороне клиента, но это не так приятно, так как вам придется инкапсулировать объекты, которые вы хотите вернуть, в объект ответа, содержащий также ошибку responseValid +.
Я не буду так высокомерен, что утвержу, что это стандарт, поэтому я буду использовать форму «Я предпочитаю».
Я предпочитаю краткий ответ (при запросе списка / статей мне нужен массив статей JSON).
В моих проектах я использую протокол HTTP для отчета о состоянии, 200 возвращает только полезную нагрузку.
400 возвращает сообщение о том, что было неправильно с запросом:
{"message" : "Missing parameter: 'param'"}
Возврат 404, если модель / элемент управления / URI не существует
Если на моей стороне была ошибка при обработке, я возвращаю 501 с сообщением:
{"message" : "Could not connect to data store."}
Из того, что я видел, достаточно много структур REST-ish, как правило, в этом направлении.
Обоснование :
JSON должен быть форматом полезной нагрузки , это не протокол сеанса. Вся идея многословных полезных данных сеанса происходит из мира XML / SOAP и различных ошибочных вариантов, которые создавали эти раздутые проекты. После того, как мы поняли, что все это было массивной головной болью, весь смысл REST / JSON заключался в том, чтобы KISS его и придерживаться HTTP. Я не думаю, что в JSend есть что-то дистанционно стандартное, и особенно не с более подробным из них. XHR будет реагировать на HTTP-ответ, если вы используете jQuery для своего AJAX (как и большинство других), вы можете использовать обратные вызовы try
/ catch
и done()
/ fail()
для захвата ошибок. Я не вижу, как инкапсуляция отчетов о состоянии в JSON более полезна.
Ниже приведена иконка json format, использующая
{ "meta": { "error_type": "OAuthException", "code": 400, "error_message": "..." } "data": { ... }, "pagination": { "next_url": "...", "next_max_id": "13872296" } }
Для чего это стоит, я делаю это по-другому. У успешного вызова есть только объекты JSON. Мне не нужен объект JSON более высокого уровня, который содержит поле успеха, указывающее true и поле полезной нагрузки, которое имеет объект JSON. Я просто возвращаю соответствующий объект JSON с 200 или любым, что подходит в диапазоне 200 для статуса HTTP в заголовке.
Однако, если есть ошибка (что-то из семейства 400), я возвращаю хорошо сформированный объект ошибки JSON. Например, если клиент выполняет POST пользователя с адресом электронной почты и номером телефона, и один из них неверен (т. Е. Я не могу вставить его в мою базовую базу данных), я верну что-то вроде этого:
{ "description" : "Validation Failed" "errors" : [ { "field" : "phoneNumber", "message" : "Invalid phone number." } ], }
Важные биты здесь состоят в том, что свойство «field» должно соответствовать полю JSON, которое не может быть проверено. Это позволяет клиентам точно знать, что пошло не так с их запросом. Кроме того, «сообщение» находится в локали запроса. Если оба «emailAddress» и «phoneNumber» были недопустимыми, массив «errors» будет содержать записи для обоих. Тело ответа JSON 409 (Conflict) может выглядеть так:
{ "description" : "Already Exists" "errors" : [ { "field" : "phoneNumber", "message" : "Phone number already exists for another user." } ], }
С кодом состояния HTTP и этим JSON у клиента есть все необходимое для детерминированного ответа на ошибки, и он не создает новый стандарт ошибок, который пытается завершить замену кодов состояния HTTP. Обратите внимание, что это происходит только в диапазоне 400 ошибок. Для чего-либо в диапазоне 200 я могу просто вернуть все, что подходит. Для меня это часто HAL-подобный объект JSON, но на самом деле это не имеет никакого значения.
Единственное, что я подумал о добавлении, – это числовой код ошибки либо в записях массива «ошибки», либо в корне самого объекта JSON. Но пока нам это не нужно.
RFC 7807: информация о проблемах для HTTP API в настоящий момент является самым близким к официальному стандарту.
Точка JSON заключается в том, что она полностью динамична и гибка. Согните его по какому-либо желанию, потому что это всего лишь набор сериализованных объектов JavaScript и массивов, внедренных в один узел.
Какой тип корневого каталога зависит от вас, то, что он содержит, зависит от того, отправляете ли вы метаданные вместе с ответом, независимо от того, задаете ли вы тип mime для application/json
или оставьте его как text/plain
(до тех пор, пока вы знаете, как обращаться с краями).
Создайте легкую схему, которая вам нравится.
Лично я обнаружил, что аналитика-отслеживание и поддержка mp3 / ogg и картинная галерея, а также текстовые сообщения и сетевые пакеты для онлайн-игр, а также сообщения в блогах и комментарии к блогам имеют очень разные требования в отношении того, что отправляется, и что получено, и как их следует потреблять.
Поэтому последнее, что я хотел бы, когда все это делаю, – попытаться заставить каждого соответствовать одному и тому же стандарту шаблона, который основан на XML2.0 или somesuch.
Тем не менее, есть много чего сказать для использования схем, которые имеют смысл для вас и хорошо продуманны.
Просто прочитайте некоторые ответы API, обратите внимание на то, что вам нравится, критикуйте то, что вы не делаете, напишите эти критические замечания и поймите, почему они втирают вас в неправильный путь, а затем подумайте о том, как применять то, что вы узнали, к тому, что вам нужно.
Они не согласны с остальными api-ответами больших гигантов программного обеспечения – Google, Facebook, Twitter, Amazon и других, хотя в приведенных выше ответах было много ссылок, в которых некоторые люди пытались стандартизировать формат ответа.
Поскольку потребности API могут отличаться, очень сложно получить всех на борту и согласиться на какой-то формат. Если у вас есть миллионы пользователей, использующих ваш API, почему вы измените формат ответа?
Ниже приводится мое мнение о формате ответа, вдохновленном Google, Twitter, Amazon и некоторыми сообщениями в Интернете:
https://github.com/adnan-kamili/rest-api-response-format
Файл Swagger:
JSON-RPC 2.0 определяет стандартный формат запроса и ответа и представляет собой глоток свежего airа после работы с API REST.
Лучший ответ для веб-apis, который может легко понять разработчики мобильных устройств.
Это для ответа «Успех»
{ "ReturnCode":"1", "ReturnMsg":"Successfull Transaction", "ReturnValue":"", "Data":{ "EmployeeName":"Admin", "EmployeeID":1 } }
Код{ "ReturnCode":"1", "ReturnMsg":"Successfull Transaction", "ReturnValue":"", "Data":{ "EmployeeName":"Admin", "EmployeeID":1 } }
Это для ответа «Ошибка»
{ "ReturnCode": "4", "ReturnMsg": "Invalid Username and Password", "ReturnValue": "", "Data": {} }