¿Formato de respuesta estándar de la API JSON?


¿Existen estándares o mejores prácticas para estructurar respuestas JSON desde una API? Obviamente, los datos de cada aplicación son diferentes, por lo que no me preocupa mucho, sino más bien la "respuesta repetitiva", si se quiere. Un ejemplo de lo que quiero decir:

Solicitud exitosa:

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

Solicitud fallida:

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

12 answers

Sí hay un par de estándares (aunque algunas libertades en la definición de estándar) que han surgido:

  1. JSON API - La API JSON también cubre la creación y actualización de recursos, no solo las respuestas.
  2. JSend - Simple y probablemente lo que ya está haciendo.
  3. OData JSON Protocol - Muy complicado.
  4. HAL - Como OData pero con el objetivo de ser HATEOAS como.

También hay API JSON formatos de descripción:

 498
Author: Adam Gent,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-05-26 10:13:51

Guía de Google JSON

Respuesta exitosa retorno data

{
  "data": {
    "id": 1001,
    "name": "Wing"
  }
}

Respuesta de errorerror

{
  "error": {
    "code": 404,
    "message": "ID not found"
  }
}

Y si su cliente es JS, puede usar if ("error" in response) {} para verificar si hay error.

 129
Author: Steely Wing,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-27 09:55:03

Supongo que un estándar de facto no ha surgido realmente (y puede que nunca). Pero a pesar de todo, aquí está mi opinión:

Solicitud exitosa:

{
  "status": "success",
  "data": {
    /* Application-specific data would go here. */
  },
  "message": null /* Or optional success message */
}

Solicitud fallida:

{
  "status": "error",
  "data": null, /* or optional error payload */
  "message": "Error xyz has occurred"
}

Ventaja: Los mismos elementos de nivel superior tanto en casos de éxito como de error

Desventaja: No hay código de error, pero si lo desea, puede cambiar el estado para que sea un código (éxito o fracaso),- o - puede agregar otro elemento de nivel superior llamado "código".

 85
Author: trungly,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-19 18:05:34

Suponiendo que la pregunta es sobre el diseño de REST webservices y más precisamente sobre el éxito/error.

Creo que hay 3 tipos diferentes de diseño.

  1. Use solo el código de estado HTTP para indicar si hubo un error e intente limitarse a los estándar (generalmente debería ser suficiente).

    • Pros: Es un estándar independiente de su api.
    • Contras: Menos información sobre lo que realmente sucedió.
  2. Uso Estado HTTP + cuerpo json (incluso si es un error). Defina una estructura uniforme para los errores (por ejemplo: código, mensaje, motivo, tipo, etc.) y utilícela para los errores, si es un éxito, simplemente devuelva la respuesta json esperada.

    • Pros: Sigue siendo estándar, ya que utiliza los códigos de estado HTTP existentes y devuelve un json que describe el error (proporciona más información sobre lo que sucedió).
    • Contras: El json de salida variará dependiendo de si es un error o éxito.
  3. Olvide el estado http (por ejemplo: siempre estado 200), utilice siempre json y agregue en la raíz de la respuesta un responseValid booleano y un objeto de error (código,mensaje,etc.) que se rellenará si es un error, de lo contrario los otros campos (éxito) se rellenarán.

    • Pros: El cliente solo trata con el cuerpo de la respuesta que es una cadena json e ignora el estado (?).

    • Desventajas: The less estándar.

Depende de usted elegir :)

Dependiendo de la API elegiría 2 o 3 (prefiero 2 para las api rest json). Otra cosa que he experimentado en el diseño de REST Api es la importancia de la documentación para cada recurso (url): los parámetros, el cuerpo, la respuesta, los encabezados, etc + ejemplos.

También le recomendaría que use jersey (implementación jax-rs) + genson (biblioteca java/json databinding). Sólo tienes que dejar caer genson + jersey en su classpath y json se admite automáticamente.

EDITAR:

  • La solución 2 es la más difícil de implementar, pero la ventaja es que puede manejar muy bien las excepciones y no solo los errores comerciales, el esfuerzo inicial es más importante, sino que gana a largo plazo.

  • La solución 3 es fácil de implementar tanto en el lado del servidor como en el cliente, pero no es tan agradable ya que tendrá que encapsular los objetos que desea devolver en una respuesta objeto que contiene también el responseValid + error.

 63
Author: eugen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-03-24 04:56:32

No seré tan arrogante al afirmar que esto es un estándar, así que usaré la forma "yo prefiero".

Prefiero una respuesta concisa (cuando solicito una lista de /articles quiero una matriz JSON de articles).

En mis diseños uso HTTP para el informe de estado, un 200 devuelve solo la carga útil.

400 devuelve un mensaje de lo que estaba mal con la solicitud:

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

Volver 404 si el modelo / controlador / URI no existe

Si hubo error con el procesamiento de mi lado, vuelvo 501 con un mensaje:

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

Por lo que he visto bastantes marcos de REST-ish tienden a estar en esta línea.

Justificación:

JSON se supone que es un formato payload, no es un protocolo de sesión. Toda la idea de las cargas útiles detalladas de sesión proviene del mundo XML/SOAP y de varias opciones equivocadas que crearon esos diseños inflados. Después de que nos dimos cuenta de que todo era un dolor de cabeza masivo, el todo el punto de REST / JSON era BESARLO, y adherirse a HTTP. No creo que haya nada remotamente estándar en ninguno de los dos JSend y especialmente no con los más detallados entre ellos. XHR reaccionará a la respuesta HTTP, si usa jQuery para su AJAX (como la mayoría lo hace) puede usar try/catch y done()/fail() devoluciones de llamada para capturar errores. No puedo ver cómo encapsular informes de estado en JSON es más útil que eso.

 17
Author: Bojan Markovic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-16 05:40:25

A continuación se muestra el formato json que instagram está utilizando

{
    "meta": {
         "error_type": "OAuthException",
         "code": 400,
         "error_message": "..."
    }
    "data": {
         ...
    },
    "pagination": {
         "next_url": "...",
         "next_max_id": "13872296"
    }
}
 15
Author: Muhammad Amin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-13 08:19:54

Por si sirve de algo hago esto de manera diferente. Una llamada exitosa solo tiene los objetos JSON. No necesito un objeto JSON de nivel superior que contenga un campo de éxito que indique true y un campo de carga útil que tenga el objeto JSON. Simplemente devuelvo el objeto JSON apropiado con un 200 o lo que sea apropiado en el rango 200 para el estado HTTP en el encabezado.

Sin embargo, si hay un error (algo en la familia 400) devuelvo un objeto de error JSON bien formado. Por ejemplo, si el cliente está publicando un Usuario con una dirección de correo electrónico y un número de teléfono y uno de estos está mal formado (es decir, no puedo insertarlo en mi base de datos subyacente) Devolveré algo como esto:

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

Los bits importantes aquí son que la propiedad "field" debe coincidir con el campo JSON exactamente que no se pudo validar. Esto permite a los clientes saber exactamente qué salió mal con su solicitud. Además, "message" está en la configuración regional de la solicitud. Si tanto el" EmailAddress " y "PhoneNumber" eran inválidos entonces el la matriz" errores " contendría entradas para ambos. Un cuerpo de respuesta JSON 409 (Conflict) podría verse así:

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

Con el código de estado HTTP y este JSON, el cliente tiene todo lo que necesita para responder a los errores de una manera determinista y no crea un nuevo estándar de error que intente reemplazar los códigos de estado HTTP. Tenga en cuenta que estos solo ocurren para el rango de 400 errores. Para cualquier cosa en el rango de 200 puedo devolver lo que sea apropiado. Para mí, a menudo es un objeto JSON similar a HAL pero eso no importa aquí.

Lo único que pensé en agregar fue un código de error numérico, ya sea en las entradas de la matriz "errores" o en la raíz del objeto JSON en sí. Pero hasta ahora no lo hemos necesitado.

 11
Author: robert_difalco,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-28 18:45:46

El RFC 7807: Problem Details for HTTP APIs es en este momento lo más cercano que tenemos a un estándar oficial.

 8
Author: Berislav Lopac,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-03 20:39:32

El punto de JSON es que es completamente dinámico y flexible. Doblarlo a cualquier capricho que desee, porque es solo un conjunto de objetos y matrices JavaScript serializados, arraigados en un solo nodo.

El tipo del rootnode depende de usted, lo que contiene depende de usted, si envía metadatos junto con la respuesta depende de usted, si establece el tipo mime en application/json o lo deja como text/plain depende de usted (siempre y cuando sepa cómo manejar el borde caso).

Construye un esquema ligero que te guste.
Personalmente, he encontrado que el seguimiento analítico y el servicio mp3/ogg y el servicio de galería de imágenes y mensajes de texto y paquetes de red para juegos en línea, y las publicaciones de blog y los comentarios de blog todos tienen requisitos muy diferentes en términos de lo que se envía y lo que se recibe y cómo deben ser consumidos.

Así que lo último que querría, al hacer todo eso, es tratar de hacer que cada uno se ajuste a el mismo estándar repetitivo, que se basa en XML2.0 o somesuch.

Dicho esto, hay mucho que decir para el uso de esquemas que tienen sentido para y están bien pensados.
Simplemente lea algunas respuestas de la API, anote lo que le gusta, critique lo que no, escriba esas críticas y comprenda por qué lo frotan de la manera equivocada, y luego piense cómo aplicar lo que aprendió a lo que necesita.

 7
Author: Norguard,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-10-09 19:06:53

No hay acuerdo sobre los formatos de respuesta de la api rest de los grandes gigantes del software: Google, Facebook, Twitter, Amazon y otros, aunque se han proporcionado muchos enlaces en las respuestas anteriores, donde algunas personas han tratado de estandarizar el formato de respuesta.

Como las necesidades de las API pueden diferir, es muy difícil que todos se sumen y acepten algún formato. Si tienes millones de usuarios usando tu API, ¿por qué cambiarías el formato de tu respuesta?

Lo siguiente es mi opinión el formato de respuesta inspirado en Google, Twitter, Amazon y algunos mensajes en Internet:

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

Archivo Swagger:

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

 7
Author: adnan kamili,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-02 09:13:05

JSON-RPC 2.0 define un formato estándar de solicitud y respuesta, y es un soplo de aire fresco después de trabajar con API REST.

 4
Author: dnault,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-11 22:09:18

La mejor respuesta para las api web que pueden entender fácilmente los desarrolladores móviles.

Esto es para una respuesta de "éxito"

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

Esto es para la respuesta de" Error "

{
    "ReturnCode": "4",
    "ReturnMsg": "Invalid Username and Password",
    "ReturnValue": "",
    "Data": {}
}
 0
Author: Manish Vadher,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-08-10 04:40:31