una sirve services restful qué para entre ejemplo diseño diferencia arquitectura web-services rest transactions standards

web-services - sirve - rest web services



Si las transacciones sobre REST no se pueden lograr, ¿cómo puede el REST ser realmente útil? (10)

Conozco sistemas de contabilidad en línea muy exitosos (SaaS) que tienen una API no transaccional basada en REST para crear, recuperar y manipular facturas, etc. Son ampliamente aclamados por su API y la facilidad de integración de su sistema con otras partes. La API es fácil de mantener, se puede utilizar desde una variedad de plataformas y garantizar la compatibilidad con versiones anteriores es razonablemente sencillo.

La falta de transacciones puede ser un verdadero dolor de cabeza, pero la mayoría de las veces, cuando sus servidores no están muy cargados, la API funciona muy bien.

A veces, menos que perfecto es lo suficientemente bueno.

Al observar REST, una de las primeras cosas que probablemente nadie notará es que no hay ninguna semántica de transacción definida, algunos dicen que esto está implícitamente en contra de lo que REST es, mientras que otros dicen que cualquier intento de hacerlo daría lugar a una "contaminación" de los sistemas REST .

Pero digamos por argumentos que REST se convirtió en una opción popular de ''api'', y cada sitio en el universo comenzó a exponer puntos de entrada relajantes.

¿Cómo son exactamente utilizables sin el comportamiento de transacción (y estoy hablando de no compensar)? porque me parece que uno de los beneficios de REST es que desglosa los componentes de los datos, esto cree que los abre para que los clientes inteligentes compren datos (y agreguen y ajusten dichos datos compuestos) de múltiples servicios. Pero si no puedo hacer mis cambios a esta composición de datos de forma atómica y aislada, el uso de REST se vuelve inútil.

A medida que pasa el tiempo y llega la necesidad de una exposición seria de datos, vamos a querer algo que sea: Simple (REST gana allí), y admite el comportamiento transaccional para que podamos manipular estos datos de manera confiable.

Ahora, he leído un argumento específico un par de veces en mi investigación, y está relacionado con cómo se supone que debemos pensar en las transacciones en REST, y el ejemplo dado es el carrito de compras, donde implícitamente tienes aislamiento porque el carrito es tuyo.

Sin embargo, no estoy de acuerdo con este argumento, en primer lugar, el aislamiento que tiene un carrito de compras es simplemente conveniente, esto no es un aislamiento de transacción. ¿Qué sucede si simultáneamente estoy haciendo una operación contra mi carro mientras una parte de mi aplicación está leyendo datos? ¿de eso? No esperaría que la parte de lectura de mi aplicación vea datos que están "todavía en transacción".

Sin mencionar el hecho de que no todos los cambios de datos tienen un modelo de transacción implícito, definitivamente las transacciones sobre múltiples servicios no lo hacen.

Me parece que las transacciones deben suceder y deben suceder de tal manera que las llamadas de REST reales sean ignorantes (lo que se suma al resto de la carga útil es un gran no, pero agregar encabezados es correcto).

He leído algunas sugerencias sobre cómo se puede crear un modelo de transacción a través de REST, y algunas de las especificaciones que se están escribiendo parecen ser muy recientes.

¿Hay alguna idea real sobre esto? ¿no debería haber algo "más" que REST para que la naturaleza simplista de REST pueda aprovecharse contra la manipulación de datos sólidos (transacciones "ácidas").

Si no, ¿se espera que elevemos la apuesta y les digamos a los desarrolladores de servicios que si quieren interactuar en un mundo de datos puros, necesitan apoyar algo que podría decirse que es monolítico como el jabón? o peor aún, intente crear su propio soporte de transacción personalizado en algo como REST, haciendo que cada servicio no sea estándar y rompa todo el poder de REST.

Gracias de antemano por cualquier pensamiento.

Editar, breve escenario agregado:

Imagine un formulario de cliente que maneja la creación de un álbum, para mayor comodidad en ese álbum, en lugar de pedirle al usuario que proporcione el uri para el recurso del artista, puede elegir de una lista de artistas (muy probablemente GET del catálogo de artistas) .

En aras de la usabilidad, el cliente puede escribir el nombre del artista manualmente para que pueda crear un artista "en línea". En el escenario de publicación, el código del cliente entiende esto, y antes de enviar la solicitud para crear el álbum, primero intenta determinar si el artista ya existe, si es así, obtiene el uri para ese artista; de lo contrario, crea el artista y consigue que los artistas lo hagan.

El código del cliente luego continúa para crear el álbum, este es el cliente más inteligente que el habitual, no se encuentra justo encima de REST y publicación "tonta", sino que tiene alguna interacción que maneja la lógica REST más pura.

Sin embargo, en este escenario, sería bueno garantizar que el artista no se crea a menos que el álbum sea, dado que el artista se creó primero.

Esto no es tan "crítico" como lo implicaría una transacción, pero define un conjunto de trabajo que el código del cliente preferiría que estuviera sucediendo como una sola operación (después de todo, está haciendo que parezca una operación única para el usuario).

La única guía que he visto para este escenario es hacer que el cliente realice una acción de compensación en caso de que falle la creación del álbum, y específicamente llamar para eliminar el artista. Pero esto parece problemático, porque el cliente asume que el artista estuvo aislado, por improbable que sea, ¿qué ocurre si otro cliente ya "vio" a ese artista y se lo asignó?

Estas son mis inquietudes con respecto a hacer cambios en los datos, y aunque ciertamente existen otras lagunas (que dicen que el artista no podría ser eliminado en una fecha posterior), esas acciones NO son transparentes (es decir, las acciones no son algo automatizado por el cliente, pero algo que un usuario ha solicitado específicamente).

Espero que eso ayude a iluminar el tema.


Creo que la mayoría de las acciones que normalmente requieren transacciones se pueden volver a procesar para que ocurran sin ellas.

Por ejemplo, la clásica transferencia bancaria. Supongamos que quiero mover $ 100 de la cuenta A a B:

Begin Transaction /Debit A, $100 /Credit B, $100 Commit Transaction

Esto podría ser reelaborado como:

/Transfer A, B, $100

De esta forma, el servidor puede hacer esto en dos pasos, pero la acción del cliente es una operación atómica única que tiene sentido lógico.

Estoy seguro de que hay muchos ejemplos en los que es más conveniente hacer un conjunto de operaciones total o nulo (y tengo curiosidad por saber qué se le ocurre a la gente para abordarlas), pero normalmente trabajo las cosas de esta manera.


Creo que las transacciones que usan REST son realmente alcanzables. Piense en una transacción como un recurso que puede crear (iniciar), editar (publicar cambios a través de) y eliminar (confirmar, revertir). Los cambios publicados en la transacción no necesitarían modificar el estado global hasta que se haya comprometido la transacción, y durante la confirmación, podría aplicar las reglas de coherencia de estado global que necesite. El recurso de la transacción estaría, por supuesto, protegido a través de las reglas de autorización.

Ya mencionó la ilustración común para este concepto:

Ahora, he leído un argumento específico un par de veces en mi investigación, y está relacionado con cómo se supone que debemos pensar en las transacciones en REST, y el ejemplo dado es el carrito de compras, donde implícitamente tienes aislamiento porque el carrito es tuyo.

Sin embargo, no estoy de acuerdo con este argumento, en primer lugar, el aislamiento que tiene un carrito de compras es simplemente conveniente, esto no es un aislamiento de transacción. ¿Qué sucede si simultáneamente estoy haciendo una operación contra mi carro mientras una parte de mi aplicación está leyendo datos? ¿de eso? No esperaría que la parte de lectura de mi aplicación vea datos que están "todavía en transacción".

¿Por qué no permitirías ver la transacción? Siempre que lo presente como lo que es, una lista de cambios pendientes, en realidad es útil proporcionar esa característica. Pero si no desea que se pueda ver, puede deshabilitar GET en el recurso.


Eche un vistazo a la API de OpenStreetMap . Creo que es una especie de "REST" y proporciona una especie de "transacciones", llamadas ''conjuntos de cambios'' allí. Es eso lo que necesita?


En realidad, las transacciones en REST funcionan de forma muy parecida a como se supone que las transacciones funcionan en los servicios SOAP tradicionales.

Las transacciones de estilo RPC, donde el cliente emite un comando de "comenzar transacción" (o alguna operación que inicia implícitamente pero no compromete una transacción), seguido de algunas operaciones adicionales, seguido de otro comando de "transacción final" implícito / explícito, son anticuadas . El mundo de los servicios web se alejó del modelo RPC hace mucho tiempo; ¡RPC / codificado en SOAP no es compatible con WS-I!

En lugar de procedimientos , los servicios SOAP de hoy se basan en el concepto de mensajes . Un solo mensaje contiene toda la información necesaria para realizar una transacción completa. Si envía un pedido, el mensaje OrderRequest contendrá la información del cliente, información del pedido, detalles del pedido, detalles de pago ... todo lo que el servidor posiblemente necesite saber sobre un solo pedido.

Tenemos WS-Transactions que definen la semántica para transacciones distribuidas, pero en realidad no están diseñadas para soportar la semántica similar a RPC del cliente, están pensadas para orquestaciones cuando necesita que varios servicios participen en la misma transacción. Por ejemplo, su servicio de pedido necesita contratar un servicio de procesamiento de pagos para validar la información de la tarjeta de crédito y publicar un pago, que debe ser retirado si el servicio de cumplimiento descubre que se está agotando, o algo así ... usted captar la idea. Todo esto tiene lugar en el entorno del servidor, por lo que realmente no hay nada que te impida hacer lo mismo en REST.

En REST, tiene recursos en lugar de mensajes , pero el concepto es bastante similar. En lugar de un mensaje OrderRequest , el cliente envía ( PUT ) un recurso de Order y el recurso debe contener la misma información necesaria para completar la transacción. Es cierto que si intenta realizar orquestaciones complejas, es posible que el REST sea un poco difícil en comparación con SOAP, pero eso no significa que no pueda seguir usando REST para su interfaz , solo que SOAP le servirá mejor para sus servicios de back-end .

La realidad, sin embargo, es que el 99% del tiempo, la gente no necesita la complejidad de WS-Transactions. Lo sé porque uso SOAP (WCF) casi exclusivamente y rara vez uso WS-Transactions.

En REST, el "estado" reside en el cliente. El servidor le dice al cliente, "aquí está toda la información que necesita darme para crear este recurso (complete esta transacción)". Pero este formulario en blanco en realidad no comienza una transacción. Depende del cliente proporcionar la información, complete el formulario, por así decirlo. Lo que hace el cliente mientras completa el formulario no le concierne al servidor; cuando el cliente finalmente envía el formulario terminado al servidor, se valida en su totalidad. Es similar a una Unidad de trabajo, excepto que el cliente es el que hace un seguimiento del "trabajo".

Espero que esto dé una mejor idea de cómo las transacciones pueden ser y se logran a través de REST. Simplemente confían en un concepto de mensaje / recurso más rico y una forma de concurrencia optimista.


Este es un tema interesante. Como mencionaste, SOAP ya tiene este tipo de funcionalidad, pero pasaron muchos años antes de que SOAP madurara hasta el punto en que la gente considerara realizar transacciones y seguridad real con ella. Antes de eso, era CORBA.

Las diversas extensiones de alto grado para SOAP, incluida la seguridad y las transacciones, requirieron mucho trabajo por parte de mucha gente para hacerlas bien. Esto no sucederá con REST de la noche a la mañana, y puede que nunca suceda.

Siento que gran parte de la popularidad actual de REST es una especie de reacción en contra de las implementaciones SOAP mal diseñadas y demasiado complicadas, lo cual es una pena, porque SOAP no tiene que ser así. Como con cualquier otra cosa, necesita un buen diseño para que funcione bien.


Porque no todos los sistemas requieren transacciones.


Si desea realizar transacciones en una aplicación ReST, en la función ReST API, generalmente se debe a que todavía tiene su amigo de servicio web técnico en la red.

Veámoslo de otra manera.

Jabón: abre una transacción, crea un registro de cliente, crea un registro de orden, confirma la transacción.

ReST busca en Google: pregunte al servidor qué hacer. El servidor dice "crear recurso del cliente", entonces POST / clientes. El servidor dice, "ahora crea un pedido si quieres", el cliente crea el pedido siguiendo el formulario.

En ReST, el protocolo de la aplicación se expresa en términos de recursos creados y manipulados, no en términos de datos que tienen límites de transacción.

Si desea tener una transacción de larga duración que abarque todas esas operaciones, es el servidor el que decide iniciarla, no el cliente.

Aún puede implementar transacciones de larga ejecución en el lado del servidor. Si intentas querer transacciones del lado del cliente, entonces supones que el cliente ya conoce todas las operaciones que va a ejecutar y los límites de transacción que existen entre esas operaciones. Si eso es lo que espera del cliente, ya ha renunciado a la naturaleza vinculante e hipermedia de una arquitectura de descanso.

De hecho, si no está haciendo ReST y está tratando de encajar en RPC sobre http, tendrá un problema al no tener transacciones.


Una operación REST puede iniciar una transacción, realizar múltiples operaciones de base de datos u otras operaciones, luego confirmar o revertir, todo dentro del alcance de una transacción.

Lo que REST no puede hacer es ser otra cosa que la raíz de una transacción. No puede iniciar una transacción, luego realizar dos operaciones REST y una operación de base de datos, y luego comprometerlas todas juntas. Así es como la situación de los servicios web ASMX en .NET. Pueden ser la raíz de una transacción, pero eso es todo. Tuvieron éxito durante años, hasta que WCF se presentó, apoyando WS-Transactions. Incluso hoy y usando WCF, la mayoría de las operaciones de servicios web no necesitan ser transaccionales en el sentido que usted está preguntando.


Voy a suponer que cuando hablas de transacciones hablas de un protocolo de Compromiso de dos fases distribuido.

Si lo entiendo correctamente, está intentando comprender cómo podríamos utilizar REST para realizar operaciones que abarcan varios sistemas si REST no puede admitir transacciones en distintas solicitudes REST. El problema es que está haciendo una suposición potencialmente errónea de que deberíamos usar transacciones para lograr consistencia. ¿Qué precio pagamos por usarlos y qué alternativas existen?

Pat Helland, que solía trabajar para Amazon y ahora está en Microsoft, escribió un documento Life más allá de las transacciones distribuidas . En el documento, el autor hace la siguiente afirmación:

Desafortunadamente, los programadores que se esfuerzan por resolver los objetivos comerciales como el comercio electrónico, la administración de la cadena de suministro, las finanzas y las aplicaciones de atención de la salud necesitan cada vez más pensar en escalar sin transacciones distribuidas. Lo hacen porque los intentos de usar transacciones distribuidas son demasiado frágiles y tienen un rendimiento bajo.

Su documento explora soluciones alternativas a las transacciones distribuidas que se escalan y funcionan bien.

Quizás REST tendrá éxito porque no admite transacciones. Aquí hay una cita de Roy Fielding, el tipo que inventó el término RESTO

Si necesita un protocolo de transacción distribuido, ¿cómo puede decir que su arquitectura se basa en REST? Simplemente no puedo ver cómo se puede obtener de una situación (de usar estado de aplicación RESTful en el cliente e hipermedia para determinar todas las transiciones de estado) a la siguiente situación de necesitar acuerdo distribuido de semántica de transacción en la que el cliente tenga que decirle al servidor cómo administrar sus propios recursos.

... por ahora considero que "transacción de descanso" es un oxímoron.

Esto es de un mensaje en la lista de discusión de REST del 9 de junio de 2009. No puedo proporcionar un enlace porque los grupos de Yahoo son inútiles.