2012-04-17 16 views
5

¿Existe alguna manera RESTful de determinar si un POST (o cualquier otro verbo no idempotente) tendrá éxito? Esto parece ser útil en casos en los que esencialmente necesita realizar múltiples solicitudes idempotentes contra diferentes servicios, cualquiera de los cuales podría fallar. Sería bueno si estas solicitudes se pudieran realizar en una "transacción" (es decir, con soporte para retrotracción), pero como esto es imposible, una alternativa es verificar si cada una de las solicitudes tendrá éxito antes de realizarlas realmente. Por ejemplo, supongamos que estoy construyendo un sistema de comercio electrónico que permite a las personas comprar camisetas con texto personalizado impreso en ellas, y este sistema requiere la integración con dos servicios diferentes: un servicio de impresión de camisetas y un servicio de pago. . Cada uno de estos tiene una API RESTful y puede fallar. (por ejemplo, la imprenta podría negarse a imprimir ciertas palabras en una camiseta, por ejemplo, y el banco podría quejarse si la tarjeta de crédito ha expirado). ¿Hay alguna manera de realizar especulativamente estas dos solicitudes, por lo que mi sistema solo procederá con ellos si ambas solicitudes parecen válidas?¿Hay alguna manera RESTful de determinar si un POST tendrá éxito?

Si no, ¿se puede resolver este problema de otra manera? ¿Creando un recurso a través de POST con status = pending, y cambiando esto a status = complete si todas las solicitudes tienen éxito? (DELETE es más complicado ...)

+0

Otro enfoque: un 'POST' con' persist = false' o 'efhemeral = true'. (Se siente un poco hacky, pero no requiere un cambio subsiguiente de 'status' - cuando realmente quiere que suceda' POST', emita nuevamente.) – mjs

Respuesta

2

HTTP define el código de estado 202 para exactamente su escenario:

202 Aceptado

La solicitud ha sido admitida a trámite, pero el tratamiento no se ha completado. Eventualmente se puede actuar sobre la solicitud o no, ya que podría no autorizarse cuando el procesamiento realmente tenga lugar. No hay ninguna posibilidad de volver a enviar un código de estado de una operación asíncrona como esta.

La respuesta 202 es intencionalmente no comprometida. Su propósito es permitir que un servidor acepte una solicitud para algún otro proceso (tal vez un proceso orientado por lotes que solo se ejecuta una vez al día) sin requerir que la conexión del agente de usuario con el servidor persista hasta que se complete el proceso. La entidad devuelta con esta respuesta DEBERÍA incluir una indicación del estado actual de la solicitud y un puntero a un monitor de estado o alguna estimación de cuándo el usuario puede esperar que se cumpla la solicitud.

Fuente: HTTP 1.1 Status Code Definition

Esto es similar a 201 Creado, excepto que usted está indicando que la solicitud no se ha completado y la entidad aún no ha sido creado. Su respuesta contendría una URL al recurso que representa la "solicitud de pedido", para que los clientes puedan verificar el estado del pedido a través de esta URL.


Para responder a su pregunta más directa: No hay manera de "prueba" si una solicitud tendrá éxito antes de hacerlo, porque que está pidiendo la clarividencia.

No es posible prever la gama de problemas técnicos que podrían ocurrir cuando intente realizar una solicitud en el futuro. La red puede no estar disponible, el servidor puede no ser capaz de acceder a su base de datos o sistemas externos de los que depende para funcionar, puede haber un corte de energía y el servidor está fuera de línea, un neutrino extraviado podría entrar en su memoria y chocar con un 0 a un 1 causando una falla catastrófica del kernel.

Para consumir un servicio remoto debe tener en cuenta las posibles fallas de cualquier solicitud independientemente de cualquier otro proceso.

Para su problema específico, si los servicios no tienen seguridad transaccional, no puede hornear ninguno allí y tiene que lidiar con esto de una manera más real. Unas pocas opciones de la parte superior de mi cabeza:

  1. Obtener la empresa camiseta para darle un mecanismo de "prueba", para que pueda ver si van a procesar cualquier orden dada sin llegar a colocarla. Podría ser que realizar un pedido con ellos es una operación de dos fases, en la que construyes el pedido en la primera fase (momento en el que validan su creación) y luego solicitas que se procese el pedido (después de haber recibido el pago) exitosamente).

  2. Primero tome el pago con tarjeta de crédito y cambie su orden a "pago". Luego intente cumplir el orden con el servicio de camiseta como un proceso asincrónico. Si falla el cumplimiento y puede identificar que el cliente intentó imprimir algo que la empresa no está preparada para producir, deberá ponerse en contacto con ellos para cambiar su pedido o producir un reembolso.

La mayoría de las organizaciones adoptarán el segundo enfoque, debido a su simplicidad técnica y la reducción del riesgo para el negocio. También tiene el beneficio de poder hacer frente al servicio de camisetas que no está disponible; el proceso asíncrono simplemente espera hasta que el servicio esté disponible y completa el pedido en ese momento.

+0

+1. Interesante que el código 202 ... –

+0

Uh, lo siento, quise decir "no idempotente" (pregunta actualizada, aunque pensando en ello de nuevo ahora, la pregunta también se aplica a 'PUT', que es idempotente ...). De todos modos, estoy bastante seguro de que 202 no se ajusta a mis propósitos: es emitido por el * servidor *, independientemente de lo que el cliente desee. (Tal vez el cliente no puede comprar la camiseta en absoluto, porque no tienen una tarjeta de crédito válida.) – mjs

+0

Entendido. Eliminó mis palabras sobre idempotencia. –

1

Exactamente. Eso se puede hacer como sugieres en tu última oración. La idea sería decopular la creación de recursos (que siempre funcionará a menos que falle la red) que representa una "solicitud en curso" de la "aceptación de la orden", que luego se puede decidir. Como POST devuelve un encabezado de "Ubicación", puede recuperar en cualquier momento el "estado" de su solicitud.

En algún momento puede ser aceptado o rechazado. Esto puede ser instantáneo o puede tomar algo de tiempo, por lo que debe diseñar su servicio con estas restricciones (es decir, permitir que el cliente verifique si se acepta su pedido o que ejecute algún tipo de servicio por hora/diario que reúna las solicitudes aceptadas) .

Cuestiones relacionadas