É compreensível ficar um pouco confuso sobre como usar corretamente o REST com base em todas as maneiras pelas quais grandes empresas projetam suas APIs REST.
Você está certo de que o REST é um sistema de Coleta de Recursos. Significa Representational State Transfer. Não é uma ótima definição se você me perguntar. Mas os principais conceitos são os 4 VERBs HTTP e são sem estado.
O ponto importante a ser observado é que você só possui 4 VERBOS com REST. Estes são GET, POST, PUT e DELETE. Seu resend
exemplo seria adicionar um novo verbo ao REST. Isso deve ser uma bandeira vermelha.
Questão 1
É importante perceber que o responsável pela chamada da API REST não deve saber que executar um PUT
em sua coleção resultaria na geração de um email. Isso cheira a um vazamento para mim. O que eles poderiam saber é que executar um PUT
poderia resultar em tarefas extras que eles poderiam consultar posteriormente. Eles saberiam disso executando um GET
recurso recentemente criado. Isso GET
retornaria o recurso e todos os Task
IDs de recurso associados a ele. Posteriormente, você poderá consultar essas tarefas para determinar seu status e até enviar um novo Task
.
Você tem poucas opções.
REST - Abordagem baseada em recursos de tarefas
Crie um tasks
recurso no qual você possa enviar tarefas específicas ao seu sistema para executar ações. Você pode executar GET
a tarefa com base na ID
devolução para determinar seu status.
Ou você pode misturar um SOAP over HTTP
serviço da Web para adicionar algum RPC à sua arquitetura.
consultando todas as tarefas para um recurso específico
GET http://server/api/myCollection/123/tasks
{ "tasks" :
[ { "22333" : "http://server/api/tasks/223333" } ]
}
exemplo de recurso de tarefa
PUT http://server/api/tasks
{
"type" : "send-email" ,
"parameters" :
{
"collection-type" : "foo" ,
"collection-id" : "123"
}
}
==> retorna o ID da tarefa
223334
GET http://server/api/tasks/223334
{
"status" : "complete" ,
"date" : "whenever"
}
REST - Usando o POST para acionar ações
Você sempre pode POST
dados adicionais para um recurso. Na minha opinião, isso violaria o espírito do REST, mas ainda seria compatível.
Você pode fazer um POST semelhante a este:
POST http://server/api/collection/123
{ "action" : "send-email" }
Você estará atualizando o recurso 123 da coleção com dados adicionais. Esses dados adicionais são essencialmente uma ação que solicita ao back-end que envie um email para esse recurso.
O problema que tenho com isso é que um GET
recurso retornará esses dados atualizados. No entanto, isso resolveria seus requisitos e ainda seria RESTful.
SOAP - Serviço da Web que aceita recursos obtidos do REST
Crie um novo WebService no qual você pode enviar emails com base no ID do recurso anterior da API REST. Não entrarei em detalhes sobre o SOAP aqui, pois a pergunta original é sobre o REST e esses dois conceitos / tecnologias não devem ser comparados, pois são maçãs e laranjas .
Questão 2
Você também tem algumas opções aqui:
Parece que muitas empresas maiores que publicam APIs REST expõem uma search
coleção que é realmente apenas uma maneira de passar parâmetros de consulta para retornar recursos.
GET http://server/api/search?q="type = myCollection & someField >= someval"
O que retornaria uma coleção de recursos REST totalmente qualificados, como:
{
"results" :
{ [
"location" : "http://server/api/myCollection/1",
"location" : "http://server/api/myCollection/9",
"location" : "http://server/api/myCollection/56"
]
}
}
Ou você pode permitir algo como MVEL como um parâmetro de consulta.
Questão 3
Eu prefiro os subníveis do que ter que voltar e consultar o outro recurso com um parâmetro de consulta. Não acredito que exista alguma regra de uma maneira ou de outra. Você pode implementar os dois lados e permitir que o chamador decida qual é o mais apropriado com base em como eles entraram no sistema pela primeira vez.
Notas
Discordo dos comentários de legibilidade de outras pessoas. Apesar do que alguns possam pensar, o REST ainda não é para consumo humano. É para consumo da máquina. Se eu quiser ver meus Tweets, uso o site regular do Twitters. Eu não realizo um REST GET com sua API. Se eu quiser fazer algo programaticamente com meus tweets, utilizarei a API REST. Sim, as APIs devem ser compreensíveis, mas você gte
não é tão ruim, apenas não é intuitivo.
A outra coisa principal com o REST é que você poderá iniciar em qualquer ponto da sua API e navegar para todos os outros recursos associados, SEM saber o URL exato dos outros recursos antes do tempo. Os resultados do GET
VERBO no REST devem retornar a URL REST completa dos recursos que referencia. Portanto, em vez de uma consulta retornar o ID de um Person
objeto, ele retornaria a URL totalmente qualificada, como http://server/api/people/13
. Em seguida, você sempre pode navegar pelos resultados de forma programática, mesmo que o URL tenha sido alterado.
Resposta ao comentário
No mundo real, de fato, existem coisas que precisam acontecer que não criam, leem, atualizam ou excluem (CRUD) um recurso.
Ações adicionais podem ser executadas em recursos. Os bancos de dados relacionais típicos suportam o conceito de procedimentos armazenados. Esses são comandos adicionais que podem ser executados em um conjunto de dados. O REST não possui esse conceito inerentemente. E não há razão para isso. Esses tipos de ações são perfeitos para serviços da Web RPC ou SOAP.
Esse é o problema geral que vejo nas APIs REST. Os desenvolvedores não gostam das limitações conceituais que cercam o REST e, portanto, o adaptam para fazer o que quiserem. Isso o impede de ser um serviço RESTful. Essencialmente, esses URLs são GET
chamados para servlets do tipo pseudo-REST.
Você tem poucas opções:
- Crie um recurso de tarefa
- Apoiar
POST
ing dados adicionais para o recurso para executar uma ação.
- Adicione os comandos adicionais através de um serviço da Web SOAP.
Se você usasse um parâmetro de consulta que VERB HTTP usaria para reenviar o email?
GET
- Isso reenvia o email E retorna os dados do recurso? E se um sistema armazenasse em cache esse URL e o tratasse como o URL exclusivo desse recurso. Toda vez que eles acessam o URL, ele reenvia um e-mail.
POST
- Na verdade, você não enviou novos dados para o recurso, apenas um parâmetro de consulta adicional.
Com base em todos os requisitos fornecidos, executar um POST
no recurso com action field
dados como POST resolverá o problema.