Estoy diseñando una nueva aplicación web que funciona con un backend REST y una interfaz HTML + JS.
Hay un método POST para cambiar una entidad (llamemos a Config), que tiene varios efectos secundarios en el estado de muchos elementos de la aplicación. Supongamos que la POST se realiza de esta manera:
POST /api/config BODY {config: ....}
Debido a esto, me gustaría mostrar una vista previa antes de que se realicen esos cambios, para que el usuario final pueda darse cuenta de lo que va a cambiar.
Lo primero que pensé fue hacer un punto final GET para la vista previa, enviando el cuerpo del nuevo estado de la entidad. De esta manera:
GET /api/preview/items BODY {config: ....}
Puede mostrar el nuevo estado de los elementos con la nueva configuración.
GET /api/preview/sales BODY {config: ....}
Podría mostrar el nuevo estado de las ventas con la nueva configuración.
Parece una buena idea usar el verbo GET ya que no estoy alterando el estado de la aplicación. Sin embargo, se desaconseja el uso de un cuerpo de solicitud con solicitudes GET .
¿Hay alguna buena práctica sobre esto? Otra opción podría ser almacenar la configuración como un borrador con un método y mostrar los resultados con otros, pero requeriría un paso adicional y tener que administrar los borradores en el servidor:
POST /api/preview/config BODY {config: ....}
GET /api/preview/items?idPreviewConfig=1
fuente
items
osales
? ¿Afecta la representación de la entidad devuelta?items
ysales
(no la estructura), dependiendo de la configuración que PUBLICES.Respuestas:
Esto es demasiado específico del dominio para tener un soporte nativo en HTTP.
En su lugar, puede hacer uno de los siguientes:
Tener un
POST /api/config/preview
. En el lado del servidor, la aplicación sabrá que no debe modificar la configuración real, sino que combinará la real con la que publicó y devolverá el resultado que indica lo que se modificó.Más tarde, si el usuario está satisfecho con el resultado, realizará una que
POST /api/config
contenga la misma carga útil que en la solicitud anterior. Esto sobrescribirá efectivamente la configuración.El beneficio de este enfoque es que no está realizando cambios importantes en la API actual. Los clientes que no necesitan la función de vista previa aún podrán actualizar las entradas como lo hacían antes.
El inconveniente es que cuando el cuerpo es grande, significaría que sería necesario enviarlo dos veces al servidor. Si este es su caso, puede utilizar el siguiente enfoque.
Tenga un
POST /api/config/prepare
que recuerde lo que se envió en un registro temporal y devuelva dos cosas: la ID del registro temporal (por ejemplo12345
) y la vista previa de los cambios.Si el usuario está satisfecho con el resultado, realizará una
POST /api/config/commit/12345
para almacenar definitivamente los cambios. De lo contrario, el registro temporal puede conservarse durante un tiempo y luego descartarse mediante un trabajo cron.El beneficio es que, aquí nuevamente, puede mantener el original
POST /api/config
intacto, y los clientes que no necesitan una vista previa no se romperán.Los inconvenientes son que (1) manejar la eliminación de registros temporales puede ser complicado (¿qué te hace pensar que una hora es suficiente? ¿Qué pasa si diez minutos después, te quedas sin memoria? ¿Cómo manejan los clientes un HTTP 404 cuando hacen un commit de un registro que expiró?) y que (2) la presentación en dos pasos de un registro puede ser más complicado de lo necesario.
Mueva la lógica de vista previa en el lado del cliente.
fuente
El punto de usar verbos HTTP específicos para diferentes llamadas de API en REST es aprovechar la mecánica y las expectativas HTTP existentes.
Usar un GET en este caso parece ir en contra de ambos.
A. ¿El cliente necesita incluir un cuerpo con un GET? inesperado
B. ¿El servidor devuelve una respuesta diferente a un get dependiendo del cuerpo? rompe las especificaciones y la mecánica de almacenamiento en caché
Si estás luchando con preguntas RESTful, mi regla es preguntarme.
"¿Cómo es esto mejor que simplemente usar POST para todo?"
A menos que haya un beneficio inmediato y obvio, vaya con la estrategia Just Use POST Stupid (JUPS)
fuente
Puede enviar un encabezado que indique al servidor "no insista en esto, solo muéstreme cuál sería el resultado si lo hiciera". P.ej
A lo que el servidor podría responder:
Tenga en cuenta que, si utiliza una O / RM basada en la Unidad de trabajo y / o transacciones por solicitud con su base de datos, puede implementar fácilmente esta funcionalidad para todos sus puntos finales sin necesidad de trabajar en ningún punto final particular: si una solicitud llega con esa opción , revierta la transacción / unidad de trabajo en lugar de confirmarla.
fuente
X-
none
pero eso, para mi gusto, contradiría demasiado la naturaleza delPOST
método.Sugeriría tratar esto de la misma manera que trata las búsquedas. Establecería un punto final POST en el
/api/config/preview
que CREA una nueva vista previa. Luego, configuraría un punto final PUT o PATCHapi/config
dependiendo de si tiene la intención de editar la configuración actual, o simplemente reemplazar toda la configuración (presumiblemente en el primer caso estaría enviando la vista previa que acaba de crear).fuente
Junto con las otras buenas respuestas, otra opción podría ser publicar la configuración como se mencionó, y tener un proceso de reversión disponible también. Creo que, al igual que la metodología Agile, es mejor tener menos miedo a los cambios al tener procedimientos más granulares, repetibles y probados, y esto le daría una copia de seguridad cuando la necesite, reduciendo el riesgo a poco o nada, dependiendo de la aplicación .
Por otra parte, si puede tener errores de configuración que afecten a todo el sistema, le gustaría manejarlo más activamente, y si ese es el caso, ¿por qué no simplemente hacer un esfuerzo para obtener una vista previa de los cambios en ese punto, desde la perspectiva de un servidor o cliente? Aunque, puedo ver cómo esta característica de vista previa podría ser más costosa de desarrollar, en los casos de uso tienen su propio conjunto de pasos dispares para seguir y probar.
fuente
RFC6648 desprecia nuevo
X-
construcciones, así que debo votar en contra de la idea de enviar un nuevo campo de encabezado. REST es un estilo de arquitectura, de lo que hablamos es RESTful, pero ignoremos eso por el momento.Debido a que REST es representativo (y una simulación no tiene representación en la realidad) y con estado (y una simulación no es un estado hasta su compromiso) debemos tener un nuevo alcance, como un alcance de simulación. Pero debemos llamarlo emulación en lugar de simulación porque la simulación incluye el proceso de simulación, pero con estado significa que tenemos un estado permanente, una solución ideal de una simulación: una emulación. Por lo tanto, debemos llamarlo emulación en la URL. Esto también podría ser una buena solución:
Hay otro enfoque ... es posible que haya notado que muchas solicitudes del cliente HTML / JavaScript pueden producir demasiadas solicitudes , lo que alcanza el límite de aproximadamente 17 solicitudes al mismo tiempo (eche un vistazo a esta página ). Puede intercambiar el uso de REST y, en lugar de entregar estados de objeto poco convincentes, puede entregar estados de página específicos de usuario enriquecidos. Ejemplo:
Saludos cordiales
fuente