No seu último esquema, você mantém verbos nos URLs dos seus recursos. Isso deve ser evitado, pois os verbos HTTP devem ser usados para esse fim. Aceite o protocolo subjacente em vez de ignorá-lo, duplicá-lo ou substituí-lo.
Basta olhar DELETE /item/delete/:id
, você coloca a mesma informação duas vezes na mesma solicitação. Isso é supérfluo e deve ser evitado. Pessoalmente, eu ficaria confuso com isso. A API realmente suporta DELETE
solicitações? E se eu colocar delete
na URL e usar um verbo HTTP diferente? Será que vai combinar alguma coisa? Em caso afirmativo, qual será escolhido? Como cliente de uma API projetada corretamente, não deveria ter que fazer essas perguntas.
Talvez você precise de alguma forma oferecer suporte a clientes que não podem emitir DELETE
ou PUT
solicitar. Se for esse o caso, eu passaria essas informações em um cabeçalho HTTP. Algumas APIs usam um X-HTTP-Method-Override
cabeçalho para esse fim específico (que, de qualquer maneira, acho feio). Eu certamente não colocaria os verbos nos caminhos.
Ir para
GET /items # Read all items
GET /items/:id # Read one item
POST /items # Create a new item
PUT /items/:id # Update one item
DELETE /items/:id # Delete one item
O que é importante sobre os verbos é que eles já estão bem definidos na especificação HTTP e permanecer alinhados com essas regras permite usar caches, proxies e possivelmente outras ferramentas externas ao seu aplicativo que entendem a semântica do HTTP, mas não a semântica do aplicativo . Observe que o motivo pelo qual você deve evitar tê-los em seus URLs não é sobre APIs RESTful que exigem URLs legíveis. Trata-se de evitar ambiguidade desnecessária.
Além disso, uma API RESTful pode mapear esses verbos (ou qualquer subconjunto deles) para qualquer conjunto de semânticas de aplicativos, desde que não atenda à especificação HTTP. Por exemplo, é perfeitamente possível construir uma API RESTful que apenas usos requisições GET, se todas as operações que ele permite são ambos segura e idempotent . O mapeamento acima é apenas um exemplo que se ajusta ao seu caso de uso e é compatível com as especificações. Não precisa necessariamente ser assim.
Lembre-se também de que uma API verdadeiramente RESTful nunca deve exigir que um programador leia documentação extensa de URLs disponíveis, desde que você esteja em conformidade com o princípio HATEOAS (Hipertexto como o mecanismo do estado do aplicativo), que é uma das principais premissas do REST . Os links podem ser totalmente incompreensíveis para os seres humanos, desde que o aplicativo cliente possa entendê-los e usá-los para descobrir possíveis transições de estado do aplicativo.
PUT
eDELETE
, eu preferiria adicioná-lo ao caminho, sem diferenciá-lo com uma string de consulta. Não é uma modificação de cadeia de consulta para uma operação existente; é uma operação separada.O primeiro.
Um URI / URL é um identificador de recurso (dica no nome: identificador uniforme de recurso). Com a primeira convenção, o recurso mencionado quando você faz "GET / user / 123" e o recurso discutido quando você faz "DELETE / user / 123" é claramente o mesmo recurso, porque eles têm a mesma URL.
Com a segunda convenção, você não pode ter certeza de que "GET / user / 123" e "DELETE / user / delete / 123" são realmente o mesmo recurso e parece implicar que você esteja excluindo um recurso relacionado em vez do recurso por si só, portanto, seria bastante surpreendente que a exclusão
/user/delete/123
realmente exclua/user/123
. Se todas as operações funcionarem em URLs diferentes, o URI não funcionará mais como um identificador de recurso.Quando você diz
DELETE /user/123
, está dizendo "excluir 'registro do usuário com o ID 123'". Enquanto você dizDELETE /user/delete/123
, o que parece estar implicando em "excluir 'registro de deletor de usuário com o ID 123'", o que provavelmente não é o que você deseja dizer. E mesmo se você usar o verbo mais correto nessa situação: "POST / user / delete / 123", que diz "faça a operação anexada a 'user deletor com id 123'", ainda é uma maneira indireta de excluir um registro (isso é semelhante à substantivo de um verbo em inglês).Uma maneira de pensar sobre a URL é tratá-la como ponteiros para objetos e recursos como objetos na programação orientada a objetos. Quando você faz
GET /user/123
,DELETE /user/123
você pode pensar pensar neles como métodos no objeto:[/user/123].get()
,[/user/123].delete()
onde a[]
é como um ponteiro dereferencing operador mas para URLs (se você sabe uma língua que tem ponteiros). Um dos princípios subjacentes do REST é a interface uniforme, ou seja, ter um conjunto pequeno e limitado de verbos / métodos que funciona para tudo em uma vasta rede de recursos / objetos.Portanto, o primeiro é melhor.
PS: é claro, isso é olhar para o REST da maneira mais pura. Às vezes, a praticidade supera a pureza e você precisa fazer concessões para clientes com morte encefálica ou estrutura que dificulte o REST adequado.
fonte
(desculpe, na primeira vez que perdi o / edit / e / delete / no (2) ...)
A idéia do URI é que ele é um identificador de um recurso endereçável , em vez de uma invocação de método . Portanto, o URI deve apontar para um recurso específico. E se você deferir o URI, sempre deverá obter o mesmo recurso.
Ou seja, você deve pensar em URIs da mesma maneira que pensa na Chave Primária de uma linha em um banco de dados. Ele identifica exclusivamente algo: Identificador Universal de Recursos.
Portanto, se você usa plural ou singular, o URI deve ser um identificador e não uma invocação . O que você está tentando fazer está no método, a saber: GET (get), PUT (criar / atualizar), DELETE (excluir) ou POST (tudo o resto).
Portanto, "/ item / delete / 123" interrompe o REST porque não aponta para um recurso, é mais uma invocação de método.
(Além disso, apenas semântica, você deve obter um URI, decidir que está desatualizado e EXCLUIR o mesmo URI - porque é um identificador. Se o GET URI não tiver "/ delete /" e DELETE, isso vai contra a semântica HTTP. Você está transmitindo 2 ou mais URIs por recurso, onde 1 fará.)
Agora, o truque é este: não existe uma definição clara e clara do que é e do que não é um recurso; portanto, o esquivo comum no REST é definir um "substantivo de processamento" e apontar o URI para ele. É praticamente um jogo de palavras, mas satisfaz a semântica.
Portanto, se, por exemplo, você realmente não puder usar isso por algum motivo:
você pode declarar ao mundo que possui um recurso de processamento "deletor" e usar
Agora, isso se parece muito com o RPC (Remote Procedure Call), mas cai na vasta lacuna da cláusula "processamento de dados" da especificação POST, nomeada na especificação HTTP.
No entanto, fazer isso é excepcional e, se você puder usar o PUT comum para criar / atualizar, DELETE para excluir e POST para anexar, criar e tudo mais, deverá fazê-lo, porque é um uso mais padrão do HTTP. Mas se você tiver um caso complicado como "confirmar" ou "publicar" ou "redigir", o caso para o uso de um nome de processador satisfaz os puristas do REST e ainda fornece a semântica de que você precisa.
fonte