Digamos que quiero tener un recurso RESTful para personas, donde el cliente pueda asignar ID.
Una persona se ve así: {"id": <UUID>, "name": "Jimmy"}
Ahora bien, ¿cómo debería guardarlo (o "PONER") el cliente?
PUT /person/UUID {"id": <UUID>, "name": "Jimmy"}
- ahora tenemos esta desagradable duplicación que tenemos que verificar todo el tiempo: ¿La identificación en el cuerpo coincide con la de la ruta?- Representación asimétrica:
PUT /person/UUID {"name": "Jimmy"}
GET /person/UUID
devoluciones{"id": <UUID>, "name": "Jimmy"}
- No hay ID en el cuerpo - ID solo en la ubicación:
PUT /person/UUID {"name": "Jimmy"}
GET /person/UUID
devoluciones{"name": "Jimmy"}
- No
POST
parece una buena idea, ya que el cliente genera la identificación.
¿Cuáles son los patrones comunes y las formas de resolverlo? Las identificaciones solo en la ubicación parece la forma más dogmáticamente correcta, pero también dificulta la implementación práctica.
id
junto con TO con id y entidad y convertidores adicionales y una sobrecarga demasiado grande para los programadores.Si es una API pública, debe ser conservador al responder, pero acepte libremente.
Con eso quiero decir, debes apoyar tanto 1 como 2. Estoy de acuerdo en que 3 no tiene sentido.
La forma de admitir tanto 1 como 2 es obtener la identificación de la URL si no se proporciona ninguna en el cuerpo de la solicitud, y si está en el cuerpo de la solicitud, validar que coincida con la identificación en la URL. Si los dos no coinciden, devuelva una respuesta 400 Bad Request.
Cuando devuelva un recurso de persona sea conservador y siempre incluya el id en el json, aunque sea opcional en el put.
fuente
Una solución a este problema implica el concepto algo confuso de "Hipertexto como motor del estado de la aplicación" o "HATEOAS". Esto significa que una respuesta REST contiene los recursos o acciones disponibles que se realizarán como hipervínculos. Con este método, que formaba parte de la concepción original de REST, los identificadores / ID únicos de los recursos son en sí mismos hipervínculos. Entonces, por ejemplo, podría tener algo como:
Luego, si desea actualizar ese recurso, puede hacer (pseudocódigo):
Una ventaja de esto es que el cliente no tiene que tener idea sobre la representación interna del servidor de los ID de usuario. Las ID pueden cambiar, e incluso las URL mismas podrían cambiar, siempre que el cliente tenga una forma de descubrirlas. Por ejemplo, al obtener una colección de personas, puede devolver una respuesta como esta:
(Por supuesto, también puede devolver el objeto de persona completo para cada persona, según las necesidades de la aplicación).
Con este método, piensa en sus objetos más en términos de recursos y ubicaciones, y menos en términos de identificación. Por tanto, la representación interna del identificador único se desacopla de la lógica de su cliente. Este fue el ímpetu original detrás de REST: crear arquitecturas cliente-servidor que estén más débilmente acopladas que los sistemas RPC que existían antes, utilizando las características de HTTP. Para obtener más información sobre HATEOAS, consulte el artículo de Wikipedia y este breve artículo .
fuente
En una inserción no es necesario agregar la identificación en la URL. De esta manera, si envía una ID en un PUT, puede interpretarlo como una ACTUALIZACIÓN para cambiar la clave principal.
INSERTAR:
ACTUALIZAR
La API JSON utiliza este estándar y resuelve algunos problemas al devolver el objeto insertado o actualizado con un enlace al nuevo objeto. Algunas actualizaciones o inserciones pueden incluir alguna lógica empresarial que cambiará campos adicionales
También verá que puede evitar obtener después de insertar y actualizar.
fuente
Esto se ha preguntado antes; vale la pena echarle un vistazo a la discusión:
¿Debería una respuesta RESTful GET devolver el ID de un recurso?
Ésta es una de esas preguntas en las que es fácil empantanarse en un debate sobre qué es y qué no es "DESCANSO" .
Por lo que vale, trato de pensar en términos de recursos consistentes y no cambiar el diseño de los mismos entre métodos. Sin embargo, en mi humilde opinión, lo más importante desde la perspectiva de la usabilidad es que usted sea consistente en toda la API.
fuente
Si bien está bien tener diferentes representaciones para diferentes operaciones, una recomendación general para PUT es contener la carga útil ENTERA . Eso significa que
id
debería estar allí también. De lo contrario, debería utilizar PATCH.Habiendo dicho eso, creo que PUT debería utilizarse principalmente para actualizaciones y
id
siempre debería pasarse también en la URL. Como resultado de eso, usar PUT para actualizar el identificador de recursos es una mala idea. Nos deja en una situación indeseable cuandoid
en la URL puede ser diferente aid
en el cuerpo.Entonces, ¿cómo resolvemos tal conflicto? Básicamente tenemos 2 opciones:
Warning
(X-API-Warn
etc.).Eso es lo más cerca que puedo estar de responder esta pregunta porque el tema en general es una cuestión de opinión.
fuente
Para su información, las respuestas aquí son incorrectas.
Ver:
https://restfulapi.net/rest-api-design-tutorial-with-example/
https://restfulapi.net/rest-put-vs-post/
https://restfulapi.net/http-methods/#patch
PONER
PARCHE
Entonces deberías usarlo de esta manera:
Las prácticas RESTful indican que no debería importar lo que PONGA en / {id}; el contenido del registro debe actualizarse al que proporciona la carga útil, pero GET / {id} aún debe vincularse al mismo recurso.
En otras palabras, PUT / 3 puede actualizar a la identificación de la carga útil a 4, pero GET / 3 aún debería vincularse a la misma carga útil (y devolver la que tiene la identificación establecida en 4).
Si está decidiendo que su API requiere el mismo identificador en el URI y la carga útil, es su trabajo asegurarse de que coincida, pero definitivamente use PATCH en lugar de PUT si está excluyendo la identificación en la carga útil que debería estar allí en su totalidad . Aquí es donde la respuesta aceptada se equivocó. PUT debe reemplazar todo el recurso, mientras que el parche puede ser parcial.
fuente
No hay nada malo en utilizar diferentes enfoques. pero creo que la mejor manera es la solución con 2nd .
se usa principalmente de esta manera, incluso el marco de la entidad usa esta técnica cuando la entidad se agrega en dbContext, la clase sin el ID generado es el ID generado por referencia en Entity Framework.
fuente
Estoy viendo esto desde un punto de vista JSON-LD / Web semántica porque es un buen camino a seguir para lograr una conformidad REST real como he descrito en estas diapositivas . Mirándolo desde esa perspectiva, no hay duda de optar por la opción (1.) ya que el ID (IRI) de un recurso web siempre debe ser igual a la URL que puedo usar para buscar / eliminar la referencia del recurso. Creo que la verificación no es realmente difícil de implementar ni computacionalmente intensiva; así que no considero que esta sea una razón válida para optar por la opción (2.). Creo que la opción (3.) no es realmente una opción ya que POST (crear nuevo) tiene una semántica diferente a PUT (actualizar / reemplazar).
fuente
Es posible que deba examinar los tipos de solicitud PATCH / PUT.
Las solicitudes PATCH se utilizan para actualizar un recurso parcialmente, mientras que en las solicitudes PUT, debe enviar todo el recurso donde se anula en el servidor.
En lo que respecta a tener un ID en la URL, creo que siempre debe tenerlo, ya que es una práctica estándar identificar un recurso. Incluso la API de Stripe funciona de esa manera.
Puede utilizar una solicitud PATCH para actualizar un recurso en el servidor con ID para identificarlo, pero no actualice el ID real.
fuente