que - lista de datos en json
¿Formato de respuesta de API JSON estándar? (12)
¿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", por así decirlo. 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!"
}
}
Guía Google JSON
data
retorno de respuesta de éxito
{
"data": {
"id": 1001,
"name": "Wing"
}
}
Error de respuesta error de respuesta
{
"error": {
"code": 404,
"message": "ID not found"
}
}
y si su cliente es JS, puede usar if ("error" in response) {}
para verificar si hay un error.
A continuación se muestra el formato json que usa Instagram.
{
"meta": {
"error_type": "OAuthException",
"code": 400,
"error_message": "..."
}
"data": {
...
},
"pagination": {
"next_url": "...",
"next_max_id": "13872296"
}
}
El RFC 7807: Detalles del problema para las API de HTTP es en este momento lo más cercano a un estándar oficial.
El punto de JSON es que es completamente dinámico y flexible. Inclínelo a cualquier antojo 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, su contenido depende de usted, ya sea que envíe metadatos junto con la respuesta, si establece el tipo mime en application/json
o lo deja como text/plain
depende de usted (siempre que sepa cómo manejar los casos de borde).
Construye un esquema ligero que te guste.
Personalmente, he descubierto que el seguimiento de análisis y el servicio de mp3 / ogg y el servicio de galería de imágenes, los mensajes de texto y los paquetes de red para juegos en línea, y las publicaciones de blogs y comentarios de blogs tienen requisitos muy diferentes en términos de lo que es Enviado y qué se recibe y cómo deben ser consumidos.
Así que lo último que me gustaría, al hacer todo eso, es tratar de hacer que cada uno cumpla con el mismo estándar estándar, que se basa en XML2.0 o algo así.
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 de la API, anote lo que le gusta, critique lo que no, escriba esas críticas y comprenda por qué lo frotan de manera incorrecta, y luego piense cómo aplicar lo que aprendió a lo que necesita.
La mejor respuesta para aplicaciones web que los desarrolladores móviles pueden entender fácilmente.
Esto es para la respuesta de "éxito"
{
"ReturnCode":"1",
"ReturnMsg":"Successfull Transaction",
"ReturnValue":"",
"Data":{
"EmployeeName":"Admin",
"EmployeeID":1
}
}
Esto es para "Error" Respuesta
{
"ReturnCode": "4",
"ReturnMsg": "Invalid Username and Password",
"ReturnValue": "",
"Data": {}
}
No hay acuerdo sobre el resto de formatos de respuesta api de grandes gigantes de 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?
A continuación, mi opinión sobre el formato de respuesta inspirado por Google, Twitter, Amazon y algunas publicaciones en Internet:
https://github.com/adnan-kamili/rest-api-response-format
Archivo de Swagger:
No seré tan arrogante como para afirmar que este es un estándar, así que usaré el formulario "Yo prefiero".
Prefiero la respuesta concisa (cuando solicito una lista de / artículos quiero una matriz JSON de artículos).
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''"}
Devuelve 404 si el modelo / controlador / URI no existe
Si hubo un error con el procesamiento de mi lado, devuelvo 501 con un mensaje:
{"message" : "Could not connect to data store."}
Por lo que he visto, algunos marcos de 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 de sesión-ish verbosa 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, todo el punto de REST / JSON era KISS, y cumplir con HTTP. No creo que haya nada remotamente estándar en ninguno de JSend y especialmente no en el más detallado entre ellos. XHR reaccionará a la respuesta HTTP, si usa jQuery para su AJAX (como la mayoría), puede usar las devoluciones de llamada try
/ catch
y done()
/ fail()
para capturar errores. No puedo ver cómo encapsular los informes de estado en JSON es más útil que eso.
Por lo que vale la pena 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 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Á ENVIANDO a un Usuario con una dirección de correo electrónico y un número de teléfono y uno de estos tiene un formato incorrecto (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 "campo" debe coincidir exactamente con el campo JSON que no pudo ser validado. Esto permite a los clientes saber exactamente qué fue lo que falló con su solicitud. Además, "mensaje" está en la configuración regional de la solicitud. Si tanto "emailAddress" como "phoneNumber" no fueran válidos, la matriz de "errores" contendría entradas para ambos. Un cuerpo de respuesta JSON 409 (Conflicto) podría tener este aspecto:
{
"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 completar los códigos de estado HTTP de reemplazo. Tenga en cuenta, esto sólo sucede 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 parecido 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 propio objeto JSON. Pero hasta ahora no lo hemos necesitado.
Sí, hay un par de estándares (aunque algunas libertades sobre la definición de estándar) que han surgido:
- jsonapi.org JSON abarca la creación y actualización de recursos, no solo las respuestas.
- JSend - Simple y probablemente lo que ya estás haciendo.
- Protocolo OData JSON - Muy complicado.
- HAL - Al igual que OData, pero con el objetivo de ser HATEOAS como.
También hay formatos de descripción de API JSON:
- Swagger
- Esquema JSON (usado por swagger, pero puedes usarlo solo)
- WADL en JSON
- RAML
- HAL porque HATEOAS en teoría se autodescribe.
Supongo que un estándar de facto realmente no ha emergido (y puede que nunca). Pero cueste lo que cueste, aquí está mi toma:
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 en casos de éxito y error
Desventaja: no hay código de error, pero si lo desea, puede cambiar el estado para que sea un código (de éxito o fracaso), o puede agregar otro elemento de nivel superior llamado "código".
Suponiendo 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 (por lo general, debería ser suficiente).
- Pros: Es un estándar independiente de tu api.
- Contras: Menos información sobre lo que realmente sucedió.
Use HTTP Status + json body (incluso si es un error). Defina una estructura uniforme para errores (por ejemplo, código, mensaje, razón, tipo, etc.) y úsela para errores, si es un éxito, simplemente devuelva la respuesta json esperada.
- Pros: Sigue siendo estándar mientras usas los códigos de estado HTTP existentes y devuelves un json que describe el error (proporcionas más información sobre lo que sucedió).
- Contras: la salida json variará dependiendo de si se trata de un error o éxito.
Olvide el estado de http (ej: siempre status 200), siempre use json y agregue en la raíz de la respuesta un responseValid booleano y un objeto de error (código, mensaje, etc.) que se completará si es 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 al diseñar 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 te recomendaría que uses jersey (implementación jax-rs) + genson (biblioteca de enlace de datos java / json). Solo tienes que colocar genson + jersey en tu classpath y json es automáticamente compatible.
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 un objeto de respuesta que contenga también el error responseValid +.
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.