¿Debería una API HTTP devolver siempre un cuerpo?

33

¿Hay algún tipo de estándar con respecto a las respuestas de la API HTTP?

Después de leer este hilo del discurso comencé a preguntarme. Estamos desarrollando nuestra API HTTP JSON pública en mi trabajo, y no devolvemos nada cuando no es estrictamente necesario (por ejemplo, PUT to / resource / {id} solo devuelve 200 cuando está OK o el código 4XX o 5XX correspondiente, pero no Cuerpo JSON)

¿Deberíamos devolver un genérico {"success":true}como se describe en el enlace de arriba, o está bien devolver un cuerpo "vacío" y manejar todo con códigos de respuesta http?

juan
fuente
8
{"éxito": verdadero} parece redundante. Intente hacer un mejor uso de los códigos HTTP. w3.org/Protocols/rfc2616/rfc2616-sec9.html
CodeART el
HTTP 1.1 presenta HEAD que carece de cuerpo, es solo la respuesta de encabezado de GET.
boctulus

Respuestas:

28

Con respecto a PUT, pero también se aplica a POST. La sección 9 de la especificación HTTP está un poco vacía en cuanto a reglas o incluso consejos (DEBE) cuando se trata del escenario que está describiendo. La línea relevante para su pregunta está más estrechamente cubierta por:

Si se crea un nuevo recurso, el servidor de origen DEBE informar al agente de usuario a través de la respuesta 201 (Creado). Si se modifica un recurso existente, DEBEN enviarse los códigos de respuesta 200 (OK) o 204 (Sin contenido) para indicar la finalización exitosa de la solicitud.

No creo que pierda el sueño por eso, pero le pregunto, ¿qué gana al agregar el fragmento de JSON en la respuesta? Acaba de salir (¡OK, puede ser demasiado!) La respuesta repite con menos precisión lo que el código de estado ya debería haberle dicho. Si su PUT resultó en un nuevo objeto, devuelva 201 (como es la intención de PUT), si actualizó un objeto, devuelva 204.

Por cierto, aparte de la API, en lugar de 200, si no devuelve nada, use 204.

Suponiendo que está desarrollando un conjunto de interfaces RESTful, no existe un estándar per se, así que haga lo que haga, documente bien, proporcione ejemplos y todo estará bien.

JohnMark13
fuente
2
Con POST, es probable que desee responder con un identificador de recurso que podría usarse para manipularlo aún más. POST /resource-> { "self" : "/resource/5" }.
Hola
1
@ Hey, usaría el locationencabezado http para eso.
CodesInChaos
@CodesInChaos, sí, eso es perfectamente legítimo, aunque nunca lo he visto así en la práctica y probablemente no preferiría eso como consumidor.
Hola
1
El caso de uso es que el cliente espera un JSON válido, incluso si la respuesta está "vacía" o no tiene contenido. Un buen ejemplo es JQuery, como lo menciona Abhi a continuación.
B Seven
12

El estándar base de HTTP no exige que se devuelva un documento con una respuesta. Por el bien de la economía, cuando un estado HTTP transmite todo lo que se requiere, el cuerpo sería un desperdicio. Sin embargo, hay estándares creados sobre HTTP que agregan nuevas reglas.

Existe un estándar abierto de API JSON que especifica:

  • Un objeto JSON DEBE estar en la raíz de cada documento de respuesta API JSON . (las cursivas representan lo que agregué para aclarar el texto)

Desafortunadamente, el estándar no especifica cómo representar un documento vacío, y es un trabajo en progreso. En el mejor de los casos, lo usaría como guía.

Algunas aplicaciones (como ElasticSearch ) proporcionan una API JSON completa y siempre tienen algunos metadatos para que pueda tener una mejor idea de cómo el servidor administra sus datos. El objeto de respuesta estándar le informa sobre el estado del índice, si la solicitud resultó en un error, cuántos nodos se vieron afectados, etc. ElasticSearch utiliza "application / json" para el tipo mime, por lo que es poco probable que apliquen las pautas en El estándar jsonapi.org.

JQuery y marcos JavaScript similares asumen que siempre habrá un documento. La pregunta es ¿cuánta comprobación de errores desea forzar a sus consumidores de API? Si encuentra un formato estándar para todas las respuestas que solo se extiende según el tipo de solicitud, satisface la necesidad de un documento de devolución y puede facilitar la depuración por parte de los consumidores de API.

Berin Loritsch
fuente
1
Esta. Cuando envío una solicitud a un servidor API JSON, lo primero que hago es verificar si la respuesta es JSON válida. Si no es válido, supongo que la solicitud falló incluso si recibí una respuesta de 200. Una respuesta / cadena en blanco no es JSON válido.
Abhi Beckert
5

No, por ejemplo, para 204 respuestas no debemos incluir el cuerpo del mensaje. {success | status | isSuccessful: true} es redundante.

En la práctica (o debería decir en una versión posterior de jquery), la respuesta vacía para el tipo de contenido de la aplicación / json genera un error. Entiendo el argumento de que debido a que es application / json debe tener un cuerpo json válido. Entonces, la respuesta vacía para el tipo de contenido de aplicación / json sería 'nulo' o '{}', que son json válidos.

Hay otra forma que debería funcionar para jquery, que no es devolver application / json para respuestas vacías. Simplemente use text / plain o algo y asegúrese de que el cliente pueda manejar ese tipo.

Tenga en cuenta que solo puedo recordar 204 por prohibir explícitamente el cuerpo del mensaje de retorno. Lo que hemos encontrado es que no siempre podemos usar 204. El problema es el encabezado de respuesta de caída de MSIE para 204 respuestas, por lo que no hay contenido y encabezados, lo cual es malo. Como muchos están usando MSIE, tuvimos que cambiarlo al estado 200.

imel96
fuente
3

No, pero ayudará a mantener la coherencia de su código. También es bueno para fines de depuración. También será de gran ayuda en el mantenimiento del sitio web. Recuerde esto: el código de error es para la máquina, el mensaje de error es para humanos. Así que le sugiero que use un cuerpo de respuesta. De todos modos, su efecto negativo es mínimo (solo unos pocos bytes enviados a través de la red) en comparación con sus beneficios. Otra cosa, también evitará que olvides escribir un cuerpo de mensaje cuando sea necesario.

pse
fuente
3

No devolvería un simple estado de éxito en la respuesta, el código de error http solo indica éxito o error. Solo incluiría el uso de la respuesta en sí para agregar información de error detallada, como códigos de error específicos de la aplicación o mensajes de error.

Para las solicitudes PUT, PATCH y POST, normalmente devuelve el estado, devuelve el estado del recurso después de que se haya aplicado la solicitud, no una respuesta vacía.

Para las solicitudes POST que representan una acción en lugar de simplemente crear un recurso (no muy RESTful, pero aún útil en la práctica), que no tiene datos útiles para devolver, devolvería una respuesta que consiste en un objeto json vacío, es decir {}. De esa manera, el cliente obtiene una respuesta válida y es poco probable que agregue información más adelante.

Para las solicitudes DELETE que devuelven 204 y un cuerpo vacío es bastante común, lo que tiene sentido ya que el recurso no existe después.

CodesInChaos
fuente
2

Sugeriría devolver solo lo que se necesita + un poco de aclaración.

Por ejemplo, dependiendo de cómo se use su API, puede incluir una copia del objeto, tal como existe después de ser guardado.

Entonces, una POST de {key: 123} podría devolver {key: 123, foo: 'bar'}.

La idea básica es que es mejor devolver el objeto que tener que volver a consultarlo.

Dicho esto, de sus consumidores API no necesitan el objeto, no hay necesidad de devolverlo.

Por lo general, devuelvo {success: true} o algo similar, cuando no se requiere ningún objeto en POST PUT and PATCH porque facilita la recepción. Dicho esto, es mejor el 99% del tiempo devolver la representación guardada del objeto, es raro que no la necesiten de todos modos, y es "más barato" enviarlo todo en una solicitud y luego en dos.

Para ser específicos, en un laboratorio se encuentra perfectamente manejar todo con solo códigos de estado, en el mundo real, es mucho mejor devolver algunos datos, incluso si son redundantes, para que los consumidores de API puedan entender fácilmente lo que estás tratando de decir.

Devolver 200 {success: true} permite a las personas escribir código en ambos sentidos:

if response.code == 200
  do stuff
end

y

if response.body.success
  do stuff
end

Además, no es tan difícil de hacer de tu lado.

Por último, (perdón por la estructura de respuesta de poos), al proporcionar una API JSON pública, estás renunciando a un gran control sobre cómo se va a usar. Algunos clientes pueden reaccionar de manera diferente a diferentes cuerpos (o falta de ellos) o códigos de estado.

coteyr
fuente
+1 para "buscar solo lo que se necesita (y no más)"
Niklas Rosencrantz