Creo que podría usar un método POST o PATCH para manejar esto, ya que generalmente diseñan para esto.
El uso de un POST
método generalmente se usa para agregar un elemento cuando se usa en un recurso de lista, pero también puede admitir varias acciones para este método. Vea esta respuesta: Cómo actualizar una colección de recursos REST . También puede admitir diferentes formatos de representación para la entrada (si corresponden a una matriz o un solo elemento).
En el caso, no es necesario definir su formato para describir la actualización.
El uso de un PATCH
método también es adecuado, ya que las solicitudes correspondientes corresponden a una actualización parcial. Según RFC5789 ( http://tools.ietf.org/html/rfc5789 ):
Varias aplicaciones que extienden el Protocolo de transferencia de hipertexto (HTTP) requieren una función para realizar modificaciones parciales de recursos. El método HTTP PUT existente solo permite la sustitución completa de un documento. Esta propuesta agrega un nuevo método HTTP, PATCH, para modificar un recurso HTTP existente.
En el caso, debe definir su formato para describir la actualización parcial.
Creo que en este caso, POST
y PATCH
son bastante similares ya que realmente no es necesario describir la operación a realizar para cada elemento. Yo diría que depende del formato de la representación a enviar.
El caso de PUT
es un poco menos claro. De hecho, cuando utilice un método PUT
, debe proporcionar la lista completa. De hecho, la representación proporcionada en la solicitud sustituirá a la del recurso de lista.
Puede tener dos opciones con respecto a las rutas de recursos.
- Usando la ruta de recursos para la lista de documentos
En este caso, debe proporcionar explícitamente el enlace de los documentos con una carpeta en la representación que proporcione en la solicitud.
Aquí hay una ruta de muestra para esto /docs
.
El contenido de tal enfoque podría ser por método POST
:
[
{ "doc_number": 1, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 2, "binder": 4, (other fields in the case of creation) },
{ "doc_number": 3, "binder": 5, (other fields in the case of creation) },
(...)
]
- Usando la ruta de recursos secundarios del elemento de enlace
Además, también podría considerar aprovechar las subrutas para describir el vínculo entre documentos y carpetas. Las sugerencias sobre la asociación entre un documento y una carpeta no tienen que especificarse ahora en el contenido de la solicitud.
Aquí hay una ruta de muestra para esto /binder/{binderId}/docs
. En este caso, enviar una lista de documentos con un método POST
o PATCH
adjuntará documentos a la carpeta con un identificador binderId
después de haber creado el documento si no existe.
El contenido de tal enfoque podría ser por método POST
:
[
{ "doc_number": 1, (other fields in the case of creation) },
{ "doc_number": 2, (other fields in the case of creation) },
{ "doc_number": 3, (other fields in the case of creation) },
(...)
]
En cuanto a la respuesta, depende de usted definir el nivel de respuesta y los errores a devolver. Veo dos niveles: el nivel de estado (nivel global) y el nivel de carga útil (nivel más delgado). También depende de usted definir si todas las inserciones / actualizaciones correspondientes a su solicitud deben ser atómicas o no.
En este caso, puede aprovechar el estado HTTP. Si todo va bien, obtienes un estatus 200
. Si no es así, otro estado como 400
si los datos proporcionados no son correctos (por ejemplo, la identificación de la carpeta no es válida) o algo más.
En este caso, 200
se devolverá un estado y depende de la representación de la respuesta describir lo que se hizo y dónde eventualmente ocurren los errores. ElasticSearch tiene un punto final en su API REST para actualización masiva. Esto podría darle algunas ideas a este nivel: http://www.elasticsearch.org/guide/en/elasticsearch/guide/current/bulk.html .
También puede implementar un procesamiento asincrónico para manejar los datos proporcionados. En este caso, las devoluciones de estado HTTP serán 202
. El cliente necesita extraer un recurso adicional para ver qué sucede.
Antes de terminar, también me gustaría notar que la especificación de OData aborda el problema con respecto a las relaciones entre entidades con la función denominada enlaces de navegación . Quizás podrías echarle un vistazo a esto ;-)
El siguiente enlace también puede ayudarlo: https://templth.wordpress.com/2014/12/15/designing-a-web-api/ .
Espero que te ayude, Thierry
GET /docs
y recuperar todos los documentos dentro de una carpeta particularGET /docs?binder_id=x
. Para eliminar un subconjunto de los recursos, ¿llamaríaDELETE /docs?binder_id=x
o debería llamarDELETE /docs
con un{"binder_id": x}
en el cuerpo de la solicitud? ¿Lo usaría alguna vezPATCH /docs?binder_id=x
para una actualización por lotes, o simplementePATCH /docs
y pasaría pares?Probablemente necesitará usar POST o PATCH, porque es poco probable que una sola solicitud que actualice y cree múltiples recursos sea idempotente.
Hacerlo
PATCH /docs
es definitivamente una opción válida. Puede encontrar complicado el uso de los formatos de parche estándar para su escenario particular. No estoy seguro de esto.Puede usar 200. También puede usar 207 - Multi Status
Esto se puede hacer de forma RESTful. La clave, en mi opinión, es tener algún recurso que esté diseñado para aceptar un conjunto de documentos para actualizar / crear.
Si usa el método PATCH, creo que su operación debería ser atómica. es decir, no usaría el código de estado 207 y luego reportaría éxitos y fallas en el cuerpo de respuesta. Si utiliza la operación POST, el enfoque 207 es viable. Tendrá que diseñar su propio cuerpo de respuesta para comunicar qué operaciones tuvieron éxito y cuáles fallaron. No tengo conocimiento de uno estandarizado.
fuente
This can be done in a RESTful way
qué se refiere la actualización y crear debe hacer por separado?PUT ING
PUT /binders/{id}/docs
Crear o actualizar y relacionar un solo documento con una carpetap.ej:
PARCHE ING
PATCH /docs
Crear documentos si no existen y relacionarlos con carpetasp.ej:
Incluiré información adicional más adelante, pero mientras tanto, si lo desea, eche un vistazo a RFC 5789 , RFC 6902 y William Durand's Please. Entrada de blog Don't Patch Like an Idiot .
fuente
docs
y asociarlos conbinders
. El cliente quiere crear carpetas si no existen y hacer la asociación si existe. En UNA SOLA solicitud a granel.En un proyecto en el que trabajé, resolvimos este problema implementando algo que llamamos solicitudes 'Batch'. Definimos una ruta
/batch
donde aceptamos json en el siguiente formato:La respuesta tiene el código de estado 207 (Multi-Status) y se ve así:
También puede agregar soporte para encabezados en esta estructura. Implementamos algo que resultó útil, que eran las variables para usar entre solicitudes en un lote, lo que significa que podemos usar la respuesta de una solicitud como entrada a otra.
Facebook y Google tienen implementaciones similares:
https://developers.google.com/gmail/api/guides/batch
https://developers.facebook.com/docs/graph-api/making-multiple-requests
Cuando desee crear o actualizar un recurso con la misma llamada, usaría POST o PUT según el caso. Si el documento ya existe, ¿desea que todo el documento sea:
En caso de que desee el comportamiento de la alternativa 1, debe usar un POST y en caso de que desee el comportamiento de la alternativa 2, debe usar PUT.
http://restcookbook.com/HTTP%20Methods/put-vs-post/
Como la gente ya sugirió, también podría optar por PATCH, pero prefiero mantener la API simple y no usar verbos adicionales si no son necesarios.
fuente
--batch_xxxx
. ¿Existen algunas diferencias cruciales entre las soluciones de Google y Facebook? Además, sobre "utilizar la respuesta de una solicitud como entrada para otra", suena muy interesante, ¿te importaría compartir más detalles? o qué tipo de escenario debería utilizarse?