Desligando uma VM por meio de uma interface REST
Este é realmente um exemplo um pouco famoso, apresentado por Tim Bray em 2009 .
Roy Fielding, discutindo o problema, compartilhou esta observação :
Pessoalmente, prefiro sistemas que tratam o estado monitorado (como status de energia) como não editável.
Em resumo, você tem um recurso de informações que retorna uma representação atual do estado monitorado; essa representação pode incluir um link hipermídia para um formulário que solicite uma alteração nesse estado, e o formulário possui outro link para um recurso para manipular (cada) solicitação de alteração.
Seth Ladd teve as principais informações sobre o problema
Passamos da Running de um estado simples de uma pessoa para um Substantivo verdadeiro, que pode ser criado, atualizado e comentado.
Levando isso de volta para a reinicialização de máquinas. Eu diria que você faria o POST para / vdc / 434 / cluster / 4894 / server / 4343 / reboots Depois de postar, você terá um URI que representa isso reboot e poderá obtê-lo para atualizações de status. Através da mágica do hiperlink, a representação da reinicialização é vinculada ao servidor que é reinicializado.
Eu acho que cunhar o espaço do URI é barato, e o URI é ainda mais barato. Crie uma coleção de atividades, modeladas como Substantivos, e POST, PUT e DELETE away!
A programação RESTful é a burocracia Vogon em escala web. Como você faz algo RESTful? Invente uma nova documentação e digitalize a documentação.
Em uma linguagem um pouco mais sofisticada, o que você está fazendo é definir o protocolo de aplicativo de domínio para "desligar uma VM" e identificar os recursos necessários para expor / implementar esse protocolo
Olhando para seus próprios exemplos
PATCH /api/virtualmachines/42
Content-Type:application/json
{ "state": "shutting down" }
Isso está ok; você realmente não está tratando a solicitação em si como seu próprio recurso de informação separado, mas ainda pode gerenciar.
Você perdeu um pouco de sua representação da mudança.
Com PATCH, no entanto, a entidade incluída contém um conjunto de instruções que descrevem como um recurso que atualmente reside no servidor de origem deve ser modificado para produzir uma nova versão.
Por exemplo, o tipo de mídia JSON Patch formata instruções como se você estivesse modificando diretamente um documento JSON
[
{ "op": "replace", "path": "state", "value": "shutting down" }
]
Em sua alternativa, a ideia está próxima, mas não obviamente correta. PUT
é uma substituição completa do estado do recurso no URL de destino ; portanto, você provavelmente não escolheria uma ortografia que se pareça com uma coleção como destino de uma representação de uma única entidade.
POST /api/virtualmachines/42/actions
É consistente com a ficção de que estamos anexando uma ação a uma fila
PUT /api/virtualmachines/42/latestAction
É consistente com a ficção de que estamos fazendo uma atualização no item de cauda na fila; é um pouco estranho fazer dessa maneira. O princípio da menor surpresa recomenda atribuir a cada PUT seu próprio identificador único, em vez de colocá-las em um único local e modificar vários recursos ao mesmo tempo.
Observe que, na medida em que estamos discutindo, a ortografia do URI-REST não se importa; /cc719e3a-c772-48ee-b0e6-09b4e7abbf8b
é um URI perfeitamente cromulento no que diz respeito ao REST. A legibilidade, como nos nomes de variáveis, é uma preocupação separada. Usar grafias consistentes com a RFC 3986 tornará as pessoas muito mais felizes.
CQRS
E se tivermos um domínio CQRS com muitas dessas "ações" (também conhecidas como comandos) que podem levar a atualizações de vários agregados ou não podem ser mapeadas para operações CRUD em recursos e sub-recursos concretos?
Greg Young no CQRS
O CQRS é um padrão muito simples que permite muitas oportunidades de arquitetura que, de outra forma, não existiriam. O CQRS não é uma consistência eventual, não está ocorrendo, não está enviando mensagens, não está tendo modelos separados para leitura e gravação, nem está usando fonte de eventos.
Quando a maioria das pessoas fala sobre CQRS, está realmente falando sobre a aplicação do padrão CQRS ao objeto que representa o limite de serviço do aplicativo.
Dado que você está falando sobre CQRS no contexto de HTTP / REST, parece razoável supor que você esteja trabalhando neste último contexto, então vamos com isso.
Surpreendentemente, este é ainda mais fácil que o seu exemplo anterior. A razão para isso é simples: comandos são mensagens .
Jim Webber descreve o HTTP como o protocolo de aplicação de um escritório da década de 1950; o trabalho é realizado recebendo mensagens e colocando-as nas caixas de entrada. A mesma idéia é válida - obtemos uma cópia em branco de um formulário, preenchemos com as especificidades que conhecemos, entregamos. Ta da
Devemos tentar modelar tantos comandos quanto concreto criar ou atualizar recursos concretos, sempre que possível (seguindo a primeira abordagem do exemplo I) e usar "pontos finais de ação" para o resto?
Sim, na medida em que os "recursos concretos" são mensagens, e não entidades no modelo de domínio.
Ideia-chave: sua API REST ainda é uma interface ; você poderá alterar o modelo subjacente sem que os clientes precisem alterar as mensagens. Ao liberar um novo modelo, você libera uma nova versão dos pontos de extremidade da Web que sabem como usar o protocolo de domínio e aplicá-lo ao novo modelo.
Um modelo CQRS é mais adequado para uma API RPC como a API?
Na verdade, não - em particular, os caches da web são um ótimo exemplo de um "modelo de leitura eventualmente consistente". Tornar cada uma das suas visualizações endereçáveis de forma independente, cada uma com suas próprias regras de cache, oferece um monte de dimensionamento gratuitamente. Há relativamente pouco apelo a uma abordagem exclusivamente de RPC para leituras.
Para gravações, é uma pergunta mais complicada: enviar todos os comandos para um único manipulador em um único endpoint ou em uma única família de endpoints é certamente mais fácil . O REST é realmente mais sobre como você encontra a comunicação onde o ponto final está para o cliente.
Tratar uma mensagem como seu próprio recurso exclusivo tem a vantagem de poder usar PUT, alertando os componentes intermediários para o fato de que o tratamento da mensagem é idempotente, para que eles possam participar de certos casos de tratamento de erros. . (Nota: que, do ponto de vista dos clientes, se os recursos tiverem URI diferente, eles serão recursos diferentes; o fato de que todos eles podem ter o mesmo código de manipulador de solicitação no servidor de origem é um detalhe de implementação oculto pelo uniforme interface).
Fielding (2008)
Devo também observar que o exposto acima ainda não é totalmente RESTful, pelo menos como eu uso o termo. Tudo o que fiz foi descrito nas interfaces de serviço, que não são mais do que qualquer RPC. Para torná-lo RESTful, eu precisaria adicionar hipertexto para introduzir e definir o serviço, descrever como executar o mapeamento usando formulários e / ou modelos de link e fornecer código para combinar as visualizações de maneiras úteis.