Стандартный формат ответа 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 520

12 ответов:

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

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

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

  • чванство
    • JSON Schema (используется swagger, но вы можете использовать его в одиночку)
  • WADL в JSON
  • RAML
  • HAL потому что HATEOAS в теории является самоописанием.

Google JSON guide

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

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

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

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

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

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

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

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

EDIT:

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

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

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

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

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

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

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

возвращение 404 если модель / контроллер / URI не существует

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

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

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

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

JSON должен быть грузоподъемностью, это не протокол. Вся идея подробных полезных нагрузок session-ish исходит из мира 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 более высокого уровня, содержащий поле success, указывающее true, и поле полезной нагрузки, содержащее объект JSON. Я просто возвращаю соответствующий объект JSON с 200 или любым другим подходящим в диапазоне 200 для состояния HTTP в заголовке.

однако, если есть ошибка (что-то в семье 400), я возвращаю хорошо сформированный объект ошибки JSON. Например, если клиент публикует пользователя с адресом электронной почты и номером телефона, и один из них искажен (т. е. я не могу вставить его в свою базовую базу данных) я верну что-то вроде этого:

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

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

{
  "description" : "Already Exists"
  "errors" : [ {
    "field" : "phoneNumber",
    "message" : "Phone number already exists for another user."
  } ],
}

С кодом состояния HTTP и этим JSON у клиента есть все, что им нужно, чтобы ответить на ошибки детерминированным способом, и он не создает новый стандарт ошибок, который пытается завершить замену кодов состояния HTTP. Обратите внимание, что это происходит только для диапазона 400 ошибок. Ни за что в диапазоне 200 я могу просто вернуть все, что подходит. Для меня это часто объект HAL-like JSON, но здесь это не имеет значения.

единственное, что я думал о добавлении, - это числовой код ошибки либо в записях массива "ошибки", либо в корне самого объекта JSON. Но пока нам это не нужно.

The RFC 7807: сведения о проблеме для HTTP API на данный момент ближе всего к официальным стандартом.

суть JSON заключается в том, что он полностью динамичен и гибок. Согните его до любой прихоти, которую вы хотели бы, потому что это просто набор сериализованных объектов JavaScript и массивов, укорененных в одном узле.

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

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

Так что последнее, что я хотел бы, когда делаю все это, это чтобы попытаться заставить каждый из них соответствовать одному и тому же шаблонному стандарту, который основан на 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 определяет стандартный формат запроса и ответа и является глотком свежего воздуха после работы с API REST.

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

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

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

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

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