¿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 "placa de respuesta", si lo desea. 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!"
}
}
Respuestas:
Sí, hay un par de estándares (aunque algunas libertades en la definición de estándar) que han surgido:
También hay formatos de descripción de API JSON:
fuente
Guía de Google JSON
Respuesta de respuesta exitosa
data
Respuesta de error volver
error
y si su cliente es JS, puede usarlo
if ("error" in response) {}
para verificar si hay un error.fuente
error
, la página de Google da un ejemplo de estoSupongo que un estándar de facto no ha surgido realmente (y puede que nunca). Pero independientemente, aquí está mi opinión:
Solicitud exitosa:
Solicitud fallida:
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 (correcto o incorrecto), o puede agregar otro elemento de nivel superior denominado "código".
fuente
messages
que es una matriz de mensajes en lugar de una sola cadena.fail
para los problemas de validación típicos, mientraserror
que solo se usa con fatalidades como errores de db.200
en los encabezados, ¿por qué necesita unstatus
campo? simplemente devuelva el objeto de datos directamente. Sabes que esto puede causar dolor adicional con lenguajes FE escritos como TypeScript.Asumiendo que su pregunta es sobre el diseño de servicios web REST y más precisamente sobre el éxito / error.
Creo que hay 3 tipos diferentes de diseño.
Use solo el código de estado HTTP para indicar si hubo un error e intente limitarse a los estándares (generalmente debería ser suficiente).
Use HTTP Status + json body (incluso si es un error). Defina una estructura uniforme para errores (ej .: código, mensaje, razón, tipo, etc.) y úsela para errores, si es un éxito, simplemente devuelva la respuesta json esperada.
Olvide el estado http (ej .: siempre estado 200), use siempre json y agregue en la raíz de la respuesta una respuesta booleana Válida y un objeto de error (código, mensaje, etc.) que se completará si se trata de un error; de lo contrario, los otros campos (éxito) están poblados.
Pros: el cliente trata solo con el cuerpo de la respuesta que es una cadena json e ignora el estado (?).
Contras: El menos estándar.
Depende de usted elegir :)
Dependiendo de la API, elegiría 2 o 3 (prefiero 2 para json rest apis). 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 de enlace de datos java / json). Solo tienes que soltar genson + jersey en tu classpath y json es compatible 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 usted 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 un objeto de respuesta que contenga también el error responseValid +.
fuente
El RFC 7807: Detalles del problema para las API HTTP es en este momento lo más cercano que tenemos a un estándar oficial.
fuente
El siguiente es el formato json que instagram está usando
fuente
No seré tan arrogante para afirmar que este es un estándar, así que usaré el formulario "Prefiero".
Prefiero una respuesta breve (cuando solicito una lista de / artículos quiero una matriz JSON de artículos).
En mis diseños utilizo 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:
Devuelve 404 si el modelo / controlador / URI no existe
Si hubo un error con el procesamiento de mi parte, devuelvo 501 con un mensaje:
Por lo que he visto, bastantes marcos REST-ish tienden a estar en esta línea.
Justificación :
Se supone que JSON es un formato de carga útil , no es un protocolo de sesión. La idea completa de las cargas útiles detalladas de sesión proviene del mundo XML / SOAP y varias opciones equivocadas que crearon esos diseños hinchados. Después de que nos dimos cuenta de que todo era un dolor de cabeza masivo, el objetivo de REST / JSON era BESARLO y adherirse a HTTP. No creo que haya nada remotamente estándar en 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
ydone()
/fail()
callbacks para capturar errores. No puedo ver cómo encapsular informes de estado en JSON es más útil que eso.fuente
Por lo que vale, 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 verdadero y un campo de carga útil que tenga el objeto JSON. Acabo de devolver el objeto JSON apropiado con un 200 o lo que sea apropiado en el rango de 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 a un usuario con una dirección de correo electrónico y un número de teléfono y uno de ellos está mal formado (es decir, no puedo insertarlo en mi base de datos subyacente), devolveré algo como esto:
Los bits importantes aquí son que la propiedad "campo" debe coincidir exactamente con el campo JSON que no se pudo validar. Esto permite a los clientes saber exactamente qué salió mal con su solicitud. Además, "mensaje" está en la configuración regional de la solicitud. Si tanto la "dirección de correo electrónico" como el "número de teléfono" no eran válidos, la matriz de "errores" contendría entradas para ambos. Un cuerpo de respuesta JSON 409 (Conflicto) podría verse así:
Con el código de estado HTTP y este JSON, el cliente tiene todo lo que necesita para responder a los errores de manera determinista y no crea un nuevo estándar de error que intente completar el reemplazo de los códigos de estado HTTP. Tenga en cuenta que esto solo ocurre para el rango de 400 errores. Para cualquier cosa en el rango 200, puedo devolver lo que sea apropiado. Para mí, a menudo es un objeto JSON similar a HAL, pero eso realmente no importa aquí.
Lo único que pensé en agregar fue un código de error numérico en las entradas de la matriz de "errores" o en la raíz del objeto JSON. Pero hasta ahora no lo hemos necesitado.
fuente
No hay acuerdo sobre el resto de los formatos de respuesta de API 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 participen y acepten algún formato. Si tiene millones de usuarios utilizando su API, ¿por qué cambiaría su formato de respuesta?
Lo siguiente es mi opinión sobre el formato de respuesta inspirado en Google, Twitter, Amazon y algunas publicaciones en Internet:
https://github.com/adnan-kamili/rest-api-response-format
Archivo Swagger:
https://github.com/adnan-kamili/swagger-sample-template
fuente
El punto de JSON es que es completamente dinámico y flexible. Inclínelo a cualquier capricho que desee, porque es solo un conjunto de objetos y matrices de JavaScript serializados, enraizados en un solo nodo.
El tipo de rootnode depende de usted, lo que contiene depende de usted, si envía metadatos junto con la respuesta depende de usted, si configura el tipo MIME
application/json
o lo deja comotext/plain
depende de usted ( siempre y cuando sepa cómo manejar los casos límite).Crea un esquema ligero que te guste.
En lo personal, he encontrado que el análisis de seguimiento y MP3 / Ogg porción y la imagen a la galería de servicio y los mensajes de texto y de red-paquetes para juegos en línea y blog-mensajes y el blog-comenta todas tienen necesidades muy diferentes en términos de lo que es enviado y lo que se recibe y cómo deben ser consumidos.
Entonces, lo último que me gustaría, al hacer todo eso, es tratar de hacer que cada uno se ajuste al mismo estándar estándar, que se basa en XML2.0 o somesuch.
Dicho esto, hay mucho que decir sobre el uso de esquemas que tienen sentido para usted y están bien pensados.
Simplemente lea algunas respuestas API, tenga en cuenta lo que le gusta, critique lo que no, escriba esas críticas y comprenda por qué lo molestan de la manera incorrecta, y luego piense en cómo aplicar lo que aprendió a lo que necesita.
fuente
JSON-RPC 2.0 define un formato estándar de solicitud y respuesta, y es una bocanada de aire fresco después de trabajar con las API REST.
fuente
code
campo sea una Cadena. Afortunadamente, la especificación nos permite introducir cualquier información que queramos en eldata
campo del error . En mis proyectos JSON-RPC, normalmente uso un solo código numérico para todos los errores de la capa de aplicación (en lugar de uno de los errores de protocolo estándar). Luego pongo la información detallada del error (incluido un código de cadena que indica el tipo de error real) en eldata
campo.Para los que vengan después, además de la respuesta aceptada que incluye HAL, JSend y JSON API, agregaría algunas otras especificaciones que vale la pena considerar:
fuente
El marco básico sugerido se ve bien, pero el objeto de error como se define es demasiado limitado. A menudo no se puede usar un solo valor para expresar el problema, y en su lugar se necesita una cadena de problemas y causas .
Investigué un poco y descubrí que el formato más común para devolver el error (excepciones) es una estructura de esta forma:
Este es el formato propuesto por el estándar de datos OASIS OASIS OData y parece ser la opción más estándar que existe, sin embargo, no parece haber altas tasas de adopción de ningún estándar en este momento. Este formato es consistente con la especificación JSON-RPC.
Puede encontrar la biblioteca completa de código abierto que implementa esto en: Mendocino JSON Utilities . Esta biblioteca admite los objetos JSON, así como las excepciones.
Los detalles se discuten en mi publicación de blog sobre Manejo de errores en JSON REST API
fuente
No existe un estándar de infracción de la ley o fuera de la ley que no sea el sentido común. Si resumimos esto como dos personas hablando, el estándar es la mejor manera en que pueden entenderse con precisión en palabras mínimas en un tiempo mínimo. En nuestro caso, "palabras mínimas" es optimizar el ancho de banda para la eficiencia del transporte y "comprender con precisión" es la estructura para la eficiencia del analizador sintáctico; que finalmente termina con menos datos y la estructura común; para que pueda pasar a través de un agujero de alfiler y se pueda analizar a través de un alcance común (al menos inicialmente).
Casi en todos los casos sugeridos, veo respuestas separadas para el escenario 'Éxito' y 'Error', lo cual es una especie de ambigüedad para mí. Si las respuestas son diferentes en estos dos casos, ¿por qué realmente necesitamos poner una bandera de 'Éxito' allí? ¿No es obvio que la ausencia de 'Error' es un 'Éxito'? ¿Es posible tener una respuesta donde 'Éxito' es VERDADERO con un conjunto 'Error'? ¿O la forma en que 'Éxito' es FALSO sin establecer 'Error'? ¿Una sola bandera no es suficiente? Preferiría tener solo el indicador 'Error', porque creo que habrá menos 'Error' que 'Éxito'.
Además, ¿deberíamos realmente hacer que el 'Error' sea una bandera? ¿Qué pasa si quiero responder con múltiples errores de validación? Entonces, me parece más eficiente tener un nodo 'Error' con cada error como hijo de ese nodo; donde un nodo 'Error' vacío (cuenta hasta cero) denotaría un 'Éxito'.
fuente
La mejor respuesta para las API web que los desarrolladores móviles pueden comprender fácilmente.
Esto es para la respuesta de "éxito"
Esto es para la respuesta de "Error"
fuente