Estou no processo de projetar uma API HTTP, espero que seja o mais RESTful possível.
Existem algumas ações cuja funcionalidade se espalha por alguns recursos e, às vezes, precisa ser desfeita.
Pensei comigo mesmo: isso parece um padrão de comando, mas como posso modelá-lo em um recurso?
Vou apresentar um novo recurso chamado XXAction, como DepositAction, que será criado através de algo como isto
POST /card/{card-id}/account/{account-id}/Deposit
AmountToDeposit=100, different parameters...
isso criará uma nova DepositAction e ativará seu método Do / Execute. Nesse caso, retornar um status HTTP criado 201 significa que a ação foi executada com sucesso.
Posteriormente, se um cliente desejar examinar os detalhes da ação, ele poderá
GET /action/{action-id}
Update / PUT deve estar bloqueado, eu acho, porque não é relevante aqui.
E para desfazer a ação, pensei em usar
DELETE /action/{action-id}
que na verdade chama o método Undo do objeto relevante e altera seu status.
Digamos que estou feliz com apenas um Do-Undo, não preciso refazer.
Esta abordagem está correta?
Existem armadilhas, razões para não usá-lo?
Isso é entendido pelo ponto de vista dos clientes?
fonte
Respostas:
Você está adicionando uma camada de abstração que é confusa
Sua API começa muito limpa e simples. Um HTTP POST cria um novo recurso de depósito com os parâmetros fornecidos. Em seguida, você sai dos trilhos introduzindo a ideia de "ações" que são um detalhe de implementação e não uma parte essencial da API.
Como alternativa, considere esta conversa HTTP ...
Agora você deseja desfazer esta operação (tecnicamente, isso não deve ser permitido em um sistema de contabilidade balanceado, mas o que é necessário):
O consumidor da API sabe que está lidando com um recurso de depósito e é capaz de determinar quais operações são permitidas nele (geralmente por meio de OPTIONS em HTTP).
Embora a implementação da operação de exclusão seja realizada por meio de "ações" hoje, não há garantia de que quando você migra esse sistema de, digamos, C # para Haskell e mantém o front-end de que o conceito secundário de uma "ação" continuaria agregando valor , enquanto o conceito principal de depósito certamente o faz.
Edite para cobrir uma alternativa para EXCLUIR e depositar
Para evitar uma operação de exclusão, mas ainda assim remover efetivamente o depósito, você deve fazer o seguinte (usando uma transação genérica para permitir depósito e retirada):
Um novo recurso de transação é criado com a quantidade exatamente oposta (-100). Isso tem o efeito de equilibrar a conta de volta para 0, negando a transação original.
Você pode considerar a criação de um terminal "utilitário" como
para obter o mesmo efeito. No entanto, isso quebra a semântica de um URI como identificador, introduzindo um verbo. É melhor aderir aos substantivos nos identificadores e manter as operações restritas aos verbos HTTP. Dessa forma, você pode criar facilmente um link permanente a partir do identificador e usá-lo para GETs e assim por diante.
fonte
O principal motivo da existência do REST é a resiliência contra erros de rede. Para que fim todas as operações devem ser idempotentes .
A abordagem básica parece razoável, mas a maneira como você descreve a
DepositAction
criação não parece ser idempotente, o que deve ser corrigido. Ao fazer com que o cliente forneça um ID exclusivo que será usado para detectar solicitações duplicadas. Então a criação mudaria paraSe outro PUT para o mesmo URL for feito com o mesmo conteúdo que anteriormente, a resposta ainda será
201 created
se o conteúdo for o mesmo e erro se o conteúdo for diferente. Isso permite ao cliente simplesmente retransmitir a solicitação quando falha, pois não pode dizer se a solicitação ou resposta foi perdida.Faz mais sentido usar o PUT, porque ele apenas grava o recurso e é idempotente, mas o uso do POST também não causaria nenhum problema.
Para examinar os detalhes da transação, o cliente terá
GET
a mesma URL, ou seja,e para desfazê-lo, ele pode EXCLUÍ-LO. Mas se ele realmente tem alguma coisa a ver com dinheiro, como sugere a amostra, sugiro COLOCÁ-LO com sinalizadores "cancelados" adicionados, em vez de prestar contas (que ainda resta vestígios de transações criadas e canceladas).
Agora você precisa escolher um método para criar o ID exclusivo. Você tem várias opções:
fonte