example diferencias http rest httpverbs

http - diferencias - Incrementar el contador de recursos de forma RESTful: PUT vs POST



rest post put get (4)

Tengo un recurso que tiene un contador. A modo de ejemplo, llamemos al perfil de recursos, y el contador es el número de vistas para ese perfil.

Según la wiki REST , las solicitudes PUT deben usarse para la creación o modificación de recursos, y deben ser idempotentes. Esa combinación está bien si estoy actualizando, por ejemplo, el nombre del perfil, porque puedo emitir una solicitud PUT que establece el nombre en algo 1000 veces y el resultado no cambia.

Para estas solicitudes PUT estándar, los navegadores hacen algo como:

PUT /profiles/123?property=value&property2=value2

Para incrementar un contador, uno llama a la url así:

PUT /profiles/123/?counter=views

Cada llamada dará como resultado que el contador se incremente. Técnicamente es una operación de actualización pero viola la idempotencia.

Estoy buscando orientación / mejores prácticas. ¿Estás haciendo esto como un POST?


Una alternativa podría ser agregar otro recurso al sistema para rastrear las visitas de un perfil. Puede llamarlo "Visualización".

Para ver todas las vistas de un perfil:

GET / profiles / 123 / visionings

Para agregar una vista a un perfil:

POST / profiles / 123 / visionings # allí, debe enviar los detalles utilizando un tipo de medio personalizado en el cuerpo de la solicitud.

Para actualizar una visualización existente:

PUT / viewings / 815 # envía atributos revisados ​​de la visualización en el cuerpo de la solicitud utilizando el tipo de medio personalizado que ha creado.

Para profundizar en los detalles de una visita:

GET / viewings / 815

Para eliminar una visualización:

DELETE / viewings / 815

Además, como está pidiendo mejores prácticas, asegúrese de que su sistema RESTful sea impulsado por hipertexto .

En su mayor parte, no hay nada de malo en utilizar los parámetros de consulta en los URI; simplemente, no le dé a sus clientes la idea de que pueden manipularlos.

En su lugar, cree un tipo de medio que incorpore los conceptos que los parámetros están tratando de modelar. Proporcione a este tipo de medio un nombre conciso, inequívoco y descriptivo. Luego documenta este tipo de medio. El problema real de exponer los parámetros de consulta en REST es que la práctica a menudo conduce a una comunicación fuera de banda y, por lo tanto, aumenta el acoplamiento entre el cliente y el servidor.

Luego, dale a tu sistema una interfaz uniforme. Por ejemplo, agregar un nuevo recurso siempre es un POST. La actualización de un recurso siempre es PUT. Eliminar es DELETE, y getiing es GET.

La parte más difícil de REST es entender cómo los tipos de medios figuran en el diseño del sistema (también es la parte que Fielding dejó fuera de su disertación porque se quedó sin tiempo). Si desea un ejemplo específico de un sistema impulsado por hipertexto que utiliza y duplica tipos de medios, consulte Sun Cloud API .


Creo que la respuesta correcta es usar PATCH. No vi que alguien más lo recomendara debería usarse para incrementar atómicamente un contador, pero creo que RFC 2068 lo dice todo muy bien:

El método PATCH es similar a PUT, excepto que la entidad contiene una lista de diferencias entre la versión original del recurso identificado por el URI de solicitud y el contenido deseado del recurso después de que se haya aplicado la acción PATCH. La lista de diferencias está en un formato definido por el tipo de medio de la entidad (por ejemplo, "aplicación / diff") y DEBE incluir suficiente información para permitir que el servidor vuelva a crear los cambios necesarios para convertir la versión original del recurso a la deseada versión.

Entonces, para actualizar el recuento de vistas del perfil 123, yo haría lo siguiente:

PATCH /profiles/123 HTTP/1.1 Host: www.example.com Content-Type: application/x-counters views + 1

Donde el tipo de medios x-counters (que acabo de inventar) está compuesto de múltiples líneas de tuplas field operator scalar de field operator scalar . views = 500 o views - 1 o views + 3 son todos sintácticamente válidos (pero pueden estar prohibidos semánticamente).

Puedo entender algunos frunciendo el ceño al inventar otro tipo de medios, pero humildemente sugiero que es más correcto que la alternativa POST / PUT. Crear un recurso para un campo, completo con su propio URI y especialmente sus propios detalles (que realmente no guardo, todo lo que tengo es un número entero) suena mal y engorroso para mí. ¿Qué pasa si tengo 23 contadores diferentes para mantener?


Creo que ambos enfoques de Yanic y Rich son interesantes. No es necesario que un PATCH sea seguro ni indefendible, pero puede serlo para ser más robusto frente a la concurrencia. La solución de Rich es ciertamente más fácil de usar en una API REST "estándar".

Ver RFC5789 :

PATCH no es seguro ni idempotente como se define en [RFC2616], Sección 9.1.

Una solicitud de PATCH se puede emitir de forma tal que sea idempotente, lo que también ayuda a evitar malos resultados de colisiones entre dos solicitudes de PATCH en el mismo recurso en un marco de tiempo similar. Las colisiones de múltiples solicitudes de PATCH pueden ser más peligrosas que las colisiones de PUT porque algunos formatos de parches deben operar desde un punto de base conocido o de lo contrario se corromperá el recurso.


Después de evaluar las respuestas anteriores, decidí que PATCH era inapropiado y, para mis propósitos, juguetear con Content-Type para una tarea trivial fue una violación del principio de KISS . Solo necesitaba incrementar n + 1, así que solo hice esto:

PUT /profiles/123$views ++

Donde ++ es el cuerpo del mensaje y el controlador lo interpreta como una instrucción para incrementar el recurso en uno.

Elegí $ para delimitar el campo / propiedad del recurso, ya que es un delimitador legal y, para mi propósito, me pareció más intuitivo que / que, en mi opinión, tiene el ambiente de transitabilidad.