Стандартный формат ответа JSON API?

существуют ли стандарты или рекомендации для структурирования ответов JSON из API? Очевидно, что данные каждого приложения разные, так что меня это не касается, а скорее "шаблон ответа", если хотите. Пример того, что я имею в виду:

удачный запрос:

{
  "success": true,
  "payload": {
    /* Application-specific data would go here. */
  }
}

не удалось запрос:

{
  "success": false,
  "payload": {
    /* Application-specific data would go here. */
  },
  "error": {
    "code": 123,
    "message": "An error occurred!"
  }
}

12 ответов


Да, есть несколько стандартов (хотя и некоторые свободы в определении стандарта), которые появились:

  1. JSON API - JSON API охватывает создание и обновление ресурсов, а не только ответы.
  2. JSend - простой и, наверное, то, что вы уже делаете.
  3. протокол OData JSON - очень сложно.
  4. хол - как OData, но стремясь быть HATEOAS нравится.

существуют также форматы описания API JSON:

  • чванство
    • в JSON-схемы (используется swagger, но вы можете использовать его отдельно)
  • WADL в JSON
  • РАМЛ
  • 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 разных типа дизайна.

  1. использовать только код состояния HTTP чтобы указать, была ли ошибка, и попытаться ограничить себя стандартными (обычно этого должно быть достаточно).

    • Pros: это стандарт, независимый от вашего api.
    • минусы: меньше информации о том, что действительно получилось.
  2. использовать статус HTTP + тело json (даже если это ошибка). Определите единую структуру для ошибок (например, код, сообщение, причина, тип и т. д.) и используйте ее для ошибок, если это успех, то просто верните ожидаемый ответ json.

    • Pros: все еще стандартно, поскольку вы используете существующие коды состояния HTTP, и вы возвращаете json, описывающий ошибку (вы предоставляете дополнительную информацию о том, что произошло).
    • минусы: Выходной json будет меняться в зависимости от того, является ли это ошибкой или успехом.
  3. забудьте статус http (например: всегда статус 200), всегда используйте json и добавьте в корень ответа логический responseValid и объект ошибки (код,сообщение и т. д.), который будет заполнен, если это ошибка, иначе заполняются другие поля (успех).

    • Pros: клиент имеет дело только с телом ответа, который является строкой json и игнорирует статус(?).

    • минусы: чем меньше стандарт.

Это до вас, чтобы выбрать :)

в зависимости от API я бы выбрал 2 или 3 (я предпочитаю 2 для JSON REST apis). Еще одна вещь, которую я испытал при разработке REST Api, - это важность документации для каждого ресурса (url): параметры, тело, ответ, заголовки и т. д. + Примеры.

Я бы также рекомендовал вам использовать Джерси (реализация jax-rs)+ genson (библиотека привязки данных java/json). Вам нужно только удалить genson + jersey в вашем пути к классам, и json автоматически поддерживается.

EDIT:

  • решение 2 труднее всего реализовать, но преимущество в том, что вы можете хорошо обрабатывать исключения и не только бизнес-ошибки, первоначальные усилия более важны, но вы выигрываете в долгосрочной перспективе.

  • решение 3 является легко реализовать как на стороне сервера, так и на стороне клиента, но это не так хорошо, как вам придется инкапсулировать объекты, которые вы хотите вернуть в объект ответа, содержащий также responseValid + error.


Я не буду так высокомерно утверждать, что это стандарт, поэтому я буду использовать форму "я предпочитаю".

Я предпочитаю краткий ответ (при запросе списка /статей я хочу массив JSON статей).

в моих проектах я использую HTTP для отчета о состоянии, a 200 возвращает только полезную нагрузку.

400 возвращает сообщение о том, что было не так с запросом:

{"message" : "Missing parameter: 'param'"}

возвращение 404 если model / controler / URI не существует

если была ошибка с обработкой на моей стороне, я возвращаю 501 сообщение:

{"message" : "Could not connect to data store."}

из того, что я видел, довольно много рамок отдыха, как правило, находятся в этом направлении.

обоснование:

JSON должен быть грузоподъемностью, это не протокол. Вся идея подробных сеансовых полезных нагрузок исходит из мира XML / SOAP и различных ошибочный выбор, который создал эти раздутые конструкции. После того, как мы поняли, что все это было огромной головной болью, весь смысл REST/JSON должен был поцеловать его и придерживаться HTTP. Я не думаю, что есть что-то отдаленно стандартный в любом JSend и особенно не с более подробным среди них. XHR будет реагировать на HTTP-ответ, если вы используете jQuery для своего AJAX (как и большинство), Вы можете использовать try/catch и done()/fail() обратные вызовы для захвата ошибок. Я не понимаю, как ... помещая отчеты о состоянии в JSON является более полезным, чем.


Ниже приведен формат JSON instagram использует

{
    "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. Например, если клиент публикует пользователя с адресом электронной почты и номером телефона, и один из них искажен (т. е. я не могу вставить его в свою базовую базу данных), я верну что-то вроде этого:

{
  "description" : "Validation Failed"
  "errors" : [ {
    "field" : "phoneNumber",
    "message" : "Invalid phone number."
  } ],
}

важными битами здесь являются то, что свойство "field" должно соответствовать полю JSON точно, что не может быть проверено. Это позволяет клиентам точно знать, что пошло не так с их просьбе. Кроме того," сообщение " находится в локали запроса. Если оба "emailAddress" и "phoneNumber" были недопустимый тогда массив" ошибки " будет содержать записи для обоих. Тело ответа 409 (конфликт) JSON может выглядеть следующим образом:

{
  "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 и массивов, укорененных в одном узле.

какой тип rootnode зависит от вас, что он содержит зависит от вас, отправляете ли вы метаданные вместе с ответом до вас, устанавливаете ли вы MIME-тип в application/json или оставьте как text/plain зависит от вас (до тех пор, пока вы знаете, как обрабатывать край случаи.)

создайте легкую схему, которая вам нравится.
Лично я обнаружил, что analytics-tracking и MP3 / ogg serving и image-gallery serving и текстовые сообщения и сетевые пакеты для онлайн-игр, а также блог-сообщения и блог-комментарии все есть очень разные требования С точки зрения того, что отправлено и что получено и как они должны потребляться.

поэтому последнее, что я хотел бы, делая все это, постараться сделать так, чтобы каждый соответствовал тот же шаблонный стандарт, который базируется на белый xml2.0 или somesuch.

тем не менее, многое можно сказать об использовании схем, которые имеют смысл вы и хорошо продуманы.
Просто прочитайте некоторые ответы API, отметьте, что вам нравится, критикуйте то, что вам не нравится, запишите эти критические замечания и поймите, почему они вас не так, а затем подумайте о том, как применить то, что вы узнали, к тому, что вам нужно.


их нет соглашения о форматах ответа REST api крупных программных гигантов-Google, Facebook, Twitter, Amazon и других, хотя многие ссылки были предоставлены в ответах выше, где некоторые люди пытались стандартизировать формат ответа.

поскольку потребности API могут отличаться, очень трудно получить всех на борту и согласиться с некоторым форматом. Если у вас миллионы пользователей, использующих ваш API, зачем менять формат ответа?

следующий мой взгляд на формат ответа вдохновлен Google, Twitter, Amazon и некоторыми сообщениями в интернете:

https://github.com/adnan-kamili/rest-api-response-format

Swagger file:

https://github.com/adnan-kamili/swagger-sample-template


JSON-RPC 2.0 определяет стандартный формат запроса и ответа и является глотком свежего воздуха после работы с REST APIs.


лучший ответ для веб-API, которые могут легко понять мобильные разработчики.

Это для ответа "успех"

{  
   "ReturnCode":"1",
   "ReturnMsg":"Successfull Transaction",
   "ReturnValue":"",
   "Data":{  
      "EmployeeName":"Admin",
      "EmployeeID":1
   }
}

Это для ответа "ошибка"

{
    "ReturnCode": "4",
    "ReturnMsg": "Invalid Username and Password",
    "ReturnValue": "",
    "Data": {}
}