Solución:
En general:
Tanto PUT como POST se pueden utilizar para crear.
Tienes que preguntar, “¿sobre qué estás realizando la acción?”, Para distinguir qué deberías usar. Supongamos que está diseñando una API para hacer preguntas. Si desea utilizar POST, lo haría con una lista de preguntas. Si desea utilizar PUT, lo haría con una pregunta en particular.
Genial, se pueden usar ambos, así que ¿cuál debería usar en mi diseño RESTful?
No es necesario que sea compatible con PUT y POST.
Lo que uses depende de ti. Pero recuerde usar el correcto dependiendo del objeto al que haga referencia en la solicitud.
Algunas consideraciones:
- ¿Nombra los objetos URL que crea explícitamente o deja que el servidor decida? Si los nombra, utilice PUT. Si deja que el servidor decida, utilice POST.
- PUT es idempotente, por lo que si PONE un objeto dos veces, no tiene ningún efecto. Esta es una buena propiedad, por lo que usaría PUT cuando sea posible.
- Puede actualizar o crear un recurso con PUT con la misma URL de objeto
- Con POST puede tener 2 solicitudes entrando al mismo tiempo haciendo modificaciones a una URL, y pueden actualizar diferentes partes del objeto.
Un ejemplo:
Escribí lo siguiente como parte de otra respuesta sobre SO con respecto a esto:
CORREO:
Se utiliza para modificar y actualizar un recurso.
POST /questions/<existing_question> HTTP/1.1 Host: www.example.com/
Tenga en cuenta que lo siguiente es un error:
POST /questions/<new_question> HTTP/1.1 Host: www.example.com/
Si la URL aún no se ha creado, no debería utilizar POST para crearla mientras especifica el nombre. Esto debería resultar en un error de ‘recurso no encontrado’ porque
<new_question>
aún no existe. Deberías PONER el<new_question>
recurso en el servidor primero.Sin embargo, podría hacer algo como esto para crear recursos usando POST:
POST /questions HTTP/1.1 Host: www.example.com/
Tenga en cuenta que en este caso no se especifica el nombre del recurso, se le devolverá la ruta URL de los nuevos objetos.
PONER:
Se utiliza para crear un recurso o sobrescribirlo. Mientras especificas la nueva URL de los recursos.
Para un nuevo recurso:
PUT /questions/<new_question> HTTP/1.1 Host: www.example.com/
Para sobrescribir un recurso existente:
PUT /questions/<existing_question> HTTP/1.1 Host: www.example.com/
Además, y de forma un poco más concisa, RFC 7231 Sección 4.3.4 estados PUT (énfasis agregado),
4.3.4. PONER
El método PUT solicita que el estado del recurso de destino sea
created
oreplaced
con el estado definido por la representación incluida en la carga útil del mensaje de solicitud.
Puede encontrar afirmaciones en la web que digan
- CORREO debe usarse para crear un recurso, y PONER debe usarse para modificar uno
- PONER debe usarse para crear un recurso, y CORREO debe usarse para modificar uno
Ninguno tiene toda la razón.
Mejor es elegir entre PUT y POST en función de la idempotencia de la acción.
PONER implica poner un recurso – reemplazar completamente lo que esté disponible en la URL dada con algo diferente. Por definición, un PUT es idempotente. Hazlo tantas veces como quieras y el resultado es el mismo. x=5
es idempotente. ¡Puede PONER un recurso ya sea que exista previamente o no (por ejemplo, para Crear o Actualizar)!
CORREO actualiza un recurso, agrega un recurso subsidiario o provoca un cambio. Un POST no es idempotente, en la forma en que x++
no es idempotente.
Según este argumento, PUT es para crear cuando conoces la URL de la cosa que vas a crear. POST se puede utilizar para crear cuando conoce la URL de la “fábrica” o del administrador de la categoría de cosas que desea crear.
asi que:
POST /expense-report
o:
PUT /expense-report/10929
- CORREO a una URL crea un recurso secundario en un servidor definido URL.
- PONER a una URL crea / reemplaza el recurso en su totalidad en el definido por el cliente URL.
- PARCHE a una URL actualizaciones parte del recurso en esa URL definida por el cliente.
La especificación relevante para PUT y POST es RFC 2616 §9.5ff.
POST crea un recurso secundario, así que PUBLICAR a /items
crea un recurso que vive bajo el /items
recurso. P.ej. /items/1
. Enviar el mismo paquete de publicación dos veces creará dos recursos.
PONER es para crear o reemplazar un recurso en un URL conocida por el cliente.
Por lo tanto: PONER es solo un candidato para CREATE donde el cliente ya conoce la URL antes de que se cree el recurso. P.ej. /blogs/nigel/entry/when_to_use_post_vs_put
ya que el título se utiliza como clave de recurso
PONER reemplaza el recurso en la URL conocida si ya existe, por lo que enviar la misma solicitud dos veces no tiene ningún efecto. En otras palabras, las llamadas a PUT son idempotentes.
El RFC se lee así:
La diferencia fundamental entre las solicitudes POST y PUT se refleja en el significado diferente del Request-URI. El URI en una solicitud POST identifica el recurso que manejará la entidad adjunta. Ese recurso puede ser un proceso de aceptación de datos, una puerta de entrada a algún otro protocolo o una entidad separada que acepta anotaciones. Por el contrario, el URI en una solicitud PUT identifica la entidad adjunta a la solicitud: el agente de usuario sabe qué URI se pretende y el servidor NO DEBE intentar aplicar la solicitud a algún otro recurso. Si el servidor desea que la solicitud se aplique a un URI diferente,
Nota: PUT se ha utilizado principalmente para actualizar recursos (reemplazándolos en su totalidad), pero recientemente ha habido un movimiento hacia el uso de PATCH para actualizar los recursos existentes, ya que PUT especifica que reemplaza todo el recurso. RFC 5789.
Actualización 2018: Hay un caso que se puede hacer para evitar PUT. Ver “DESCANSAR sin PONER”
Con la técnica “REST without PUT”, la idea es que los consumidores se vean obligados a publicar nuevos recursos de solicitud “sustantivos”. Como se discutió anteriormente, cambiar la dirección de correo de un cliente es un POST a un nuevo recurso “ChangeOfAddress”, no un PUT de un recurso de “Cliente” con un valor de campo de dirección de correo diferente.
tomado de REST API Design – Resource Modeling por Prakash Subramaniam de Thoughtworks
Esto obliga a la API a evitar problemas de transición de estado con varios clientes que actualizan un solo recurso, y se adapta mejor al abastecimiento de eventos y CQRS. Cuando el trabajo se realiza de forma asincrónica, parece apropiado POSTAR la transformación y esperar a que se aplique.