Estoy en el proceso de diseñar una API HTTP, con la esperanza de que sea lo más RESTANTE posible.
Hay algunas acciones cuya funcionalidad se extiende sobre unos pocos recursos, y en algún momento debe deshacerse.
Pensé para mí mismo, esto suena como un patrón de comando, pero ¿cómo puedo modelarlo en un recurso?
Introduciré un nuevo recurso llamado XXAction, como DepositAction, que se creará a través de algo como esto
POST /card/{card-id}/account/{account-id}/Deposit
AmountToDeposit=100, different parameters...
esto creará una nueva DepositAction y activará su método Do / Execute. En este caso, devolver un estado HTTP creado 201 significa que la acción se ha ejecutado con éxito.
Más tarde, si un cliente desea ver los detalles de la acción, puede
GET /action/{action-id}
Supongo que la actualización / PUT debería estar bloqueada, porque no es relevante aquí.
Y para deshacer la acción, pensé en usar
DELETE /action/{action-id}
que en realidad llamará al método Deshacer del objeto relevante y cambiará su estado.
Digamos que estoy contento con un solo deshacer, no necesito rehacer.
¿Está bien este enfoque?
¿Hay algún inconveniente, razones para no usarlo?
¿Se entiende esto desde el punto de vista de los clientes?
fuente
Respuestas:
Estás agregando una capa de abstracción que es confusa
Su API comienza muy limpia y simple. Una POST HTTP crea un nuevo recurso de depósito con los parámetros dados. Luego, se sale del camino introduciendo la idea de "acciones" que son un detalle de implementación en lugar de una parte central de la API.
Como alternativa, considere esta conversación HTTP ...
Ahora desea deshacer esta operación (técnicamente, esto no debería permitirse en un sistema de contabilidad equilibrado, pero qué bueno):
El consumidor de API sabe que está tratando con un recurso de Depósito y puede determinar qué operaciones están permitidas en él (generalmente a través de OPCIONES en HTTP).
Aunque la implementación de la operación de eliminación se lleva a cabo a través de "acciones" hoy en día, no hay garantía de que cuando migre este sistema de, por ejemplo, C # a Haskell y mantenga el front-end que el concepto secundario de una "acción" continuaría agregando valor , mientras que el concepto principal de Depósito ciertamente lo hace.
Editar para cubrir una alternativa a DELETE y Deposit
Para evitar una operación de eliminación, pero aún así eliminar efectivamente el Depósito, debe hacer lo siguiente (utilizando una Transacción genérica para permitir Depósito y Retiro):
Se crea un nuevo recurso de transacción que tiene exactamente la cantidad opuesta (-100). Esto tiene el efecto de equilibrar la cuenta de nuevo a 0, negando la transacción original.
Puede considerar crear un punto final de "utilidad" como
para obtener el mismo efecto. Sin embargo, esto rompe la semántica de un URI como un identificador al introducir un verbo. Es mejor atenerse a los sustantivos en los identificadores y mantener las operaciones restringidas a los verbos HTTP. De esa manera, puede crear fácilmente un enlace permanente a partir del identificador y utilizarlo para GET, etc.
fuente
La razón principal de la existencia de REST es la resistencia frente a errores de red. Para lo cual todas las operaciones deben ser idempotentes .
El enfoque básico parece razonable, pero la forma en que describe la
DepositAction
creación no parece ser idempotente, lo que debería solucionarse. Al hacer que el cliente proporcione una identificación única que se utilizará para detectar solicitudes duplicadas. Entonces la creación cambiaría aSi se realiza otro PUT a la misma URL con el mismo contenido que anteriormente, la respuesta aún debería ser
201 created
si el contenido es el mismo y un error si el contenido es diferente. Esto permite que el cliente simplemente retransmita la solicitud cuando falla, ya que el cliente no puede saber si la solicitud o la respuesta se perdieron.Tiene más sentido usar PUT, porque solo escribe el recurso y es idempotente, pero el uso de POST tampoco causaría ningún problema.
Para ver los detalles de la transacción, el cliente tendrá
GET
la misma URL, es deciry para deshacerlo, puede BORRARLO. Pero si realmente tiene algo que ver con el dinero, como sugiere la muestra, sugeriría PONERLO con banderas "canceladas" agregadas, en cambio, para la rendición de cuentas (que queda rastro de transacción creada y cancelada).
Ahora debe elegir un método para crear la identificación única. Tienes varias opciones:
fuente