Apagar una VM a través de una interfaz REST
Este es en realidad un ejemplo algo famoso, presentado por Tim Bray en 2009 .
Roy Fielding, discutiendo el problema, compartió esta observación :
Personalmente, prefiero los sistemas que tratan el estado monitoreado (como el estado de energía) como no editable.
En resumen, tiene un recurso de información que devuelve una representación actual del estado supervisado; esa representación puede incluir un enlace hipermedia a un formulario para solicitar un cambio a ese estado, y el formulario tiene otro enlace a un recurso para manejar (cada) solicitud de cambio.
Seth Ladd tenía las ideas clave sobre el problema.
Hemos convertido la ejecución de un estado simple de una persona en un nombre verdadero que se puede crear, actualizar y comentar.
Llevando esto de vuelta a las máquinas de reinicio. Yo diría que POSTARÍAS en / vdc / 434 / cluster / 4894 / server / 4343 / reboots Una vez que hayas publicado, tienes un URI que representa este reinicio, y puedes OBTENERLO para actualizaciones de estado. A través de la magia del hipervínculo, la representación del reinicio se vincula al servidor que se reinicia.
Creo que acuñar espacio URI es barato, y los URI son aún más baratos. ¡Crea una colección de actividades, modeladas como sustantivos, y POST, PUT y DELETE!
La programación RESTful es la burocracia de Vogon a escala web. ¿Cómo haces algo RESTful? Inventar nuevos documentos para ello y digitalizar el papeleo.
En un lenguaje algo más sofisticado, lo que está haciendo es definir el protocolo de aplicación de dominio para "apagar una VM" e identificar los recursos que necesita para exponer / implementar ese protocolo
Mirando tus propios ejemplos
PATCH /api/virtualmachines/42
Content-Type:application/json
{ "state": "shutting down" }
Está bien; en realidad no está tratando la solicitud en sí como su propio recurso de información por separado, pero aún podría administrarla.
Te has perdido un poco en tu representación del cambio.
Sin embargo, con PATCH, la entidad adjunta contiene un conjunto de instrucciones que describen cómo se debe modificar un recurso que actualmente reside en el servidor de origen para producir una nueva versión.
Por ejemplo, el tipo de medio JSON Patch formatea las instrucciones como si estuviera modificando directamente un documento JSON
[
{ "op": "replace", "path": "state", "value": "shutting down" }
]
En su alternativa, la idea es cercana, pero obviamente no es correcta. PUT
es un reemplazo completo del estado del recurso en la URL de destino , por lo que probablemente no elegiría una ortografía que parezca una colección como el objetivo de una representación de una sola entidad.
POST /api/virtualmachines/42/actions
Es coherente con la ficción de que estamos agregando una acción a una cola
PUT /api/virtualmachines/42/latestAction
Es coherente con la ficción de que estamos haciendo una actualización del elemento de cola en la cola; Es un poco extraño hacerlo de esta manera. El principio de menor sorpresa recomienda dar a cada PUT su propio identificador único, en lugar de ponerlos a todos en un solo lugar y modificar múltiples recursos al mismo tiempo.
Tenga en cuenta que, en la medida en que estamos discutiendo la ortografía de URI, a REST no le importa; /cc719e3a-c772-48ee-b0e6-09b4e7abbf8b
es un URI perfectamente cromulento en lo que respecta a REST. La legibilidad, como con los nombres de variables, es una preocupación separada. El uso de ortografías que sean consistentes con RFC 3986 hará que las personas sean mucho más felices.
CQRS
¿Qué sucede si tenemos un dominio CQRS con muchas de esas "acciones" (también conocidas como comandos) que podrían conducir a actualizaciones de múltiples agregados o no pueden asignarse a operaciones CRUD en recursos y subrecursos concretos?
Greg Young en CQRS
CQRS es un patrón muy simple que permite muchas oportunidades para la arquitectura que de otro modo no existirían. CQRS no es una coherencia eventual, no está produciendo eventos, no está enviando mensajes, no tiene modelos separados para leer y escribir, ni está utilizando el abastecimiento de eventos.
Cuando la mayoría de las personas habla de CQRS, en realidad están hablando de aplicar el patrón CQRS al objeto que representa el límite de servicio de la aplicación.
Dado que está hablando de CQRS en el contexto de HTTP / REST, parece razonable suponer que está trabajando en este último contexto, así que vamos con eso.
Este, sorprendentemente, es incluso más fácil que su ejemplo anterior. La razón de esto es simple: los comandos son mensajes .
Jim Webber describe HTTP como el protocolo de aplicación de una oficina de la década de 1950; el trabajo se realiza tomando mensajes y colocándolos en bandejas de entrada. La misma idea es válida: obtenemos una copia en blanco de un formulario, lo completamos con los detalles que conocemos y lo entregamos. Ta da
¿Deberíamos tratar de modelar tantos comandos como concreto crea o actualiza en recursos concretos, siempre que sea posible (siguiendo el primer enfoque del ejemplo I) y usar "puntos finales de acción" para el resto?
Sí, en la medida en que los "recursos concretos" son mensajes, en lugar de entidades en el modelo de dominio.
Idea clave: su API REST sigue siendo una interfaz ; debería poder cambiar el modelo subyacente sin que los clientes necesiten cambiar los mensajes. Cuando lanza un nuevo modelo, lanza una nueva versión de sus puntos finales web que saben cómo tomar su protocolo de dominio y aplicarlo al nuevo modelo.
¿Es un modelo CQRS más adecuado para un RPC como API?
En realidad no, en particular, los cachés web son un gran ejemplo de un "modelo de lectura eventualmente consistente". Hacer que cada una de sus vistas sea direccionable de forma independiente, cada una con sus propias reglas de almacenamiento en caché, le brinda un montón de escalado de forma gratuita. Hay relativamente poco atractivo para un enfoque exclusivamente RPC para las lecturas.
Para las escrituras, es una pregunta clave: enviar todos los comandos a un único controlador en un único punto final, o una sola familia de puntos finales, es ciertamente más fácil . REST es realmente más sobre cómo encontrar la comunicación del punto final al cliente.
Tratar un mensaje como su propio recurso único tiene la ventaja de que puede usar PUT, alertando a los componentes intermediarios sobre el hecho de que el manejo del mensaje es idempotente, para que puedan participar en ciertos casos de manejo de errores. . (Nota: desde el punto de vista de los clientes, si los recursos tienen un URI diferente, entonces son recursos diferentes; el hecho de que todos puedan tener el mismo código de controlador de solicitud en el servidor de origen es un detalle de implementación oculto por el uniforme interfaz).
Fielding (2008)
También debo tener en cuenta que lo anterior aún no es completamente RESTful, al menos cómo uso el término. Todo lo que he hecho es describir las interfaces de servicio, que no es más que cualquier RPC. Para que sea RESTful, necesitaría agregar hipertexto para presentar y definir el servicio, describir cómo realizar el mapeo usando formularios y / o plantillas de enlaces, y proporcionar código para combinar las visualizaciones de maneras útiles.