REST não é CRUD
Será que RESTFul é um nome bonito para CRUD? Te disseram que API's RESTFul utilizam substantivos ao invés de verbos? Coisas ao invés de ações? Veja neste post como uma informação mal formulada pode atrapalhar o design de milhares de times.
Os verbos HTTP parecem estar diretamente ligado com o CRUD:
- Create -> POST
- Read -> GET
- Update -> PUT / PATCH
- Delete -> DELETE
Por causa de uma confusão na classificação de Resource, acabam relacionando REST diretamente a um CRUD. Por causa desse erro de classificação, quem busca criar api's verdadeiramente RESTFul terá dificuldades em seguir as "bases" do conceito.
Resources
Há um senso comum que a classificação de um Resource deve seguir certas regras:
- Coisa ao invés de ação
- Substantivos ao invés de verbos
A maioria dos exemplo que encontramos para explicar como classificar um resource, não expöe a complexidade dos objetos. Com exemplos simples. Veja esse:
POST /users # Cria um usuario
PUT /users/{id} # Atualiza o usuario
PATCH /users/{id} # Parcialmente atualiza o usuario
DELETE /users/{id # Remove o usuario
Perfeito, certo? Utiliza os verbos HTTP de maneira correta. Classificou o recurso como um substantivo. É possivel atualizar, remover, buscar e criar um recurso de usuário.
O problema é que no mundo real, no seu dia a dia, as API's não são tão simples. Elas possuem a complexidade do negócio. Muitas vezes um recurso é um objeto do sistema.
Apenas uma URL para atualizar e mudar seu estado se torna insuficiente. E se ele for um objeto do seu sistema, haverá comportamentos. E é necessário expôr certos comportamentos através da API.
Veja o exemplo abaixo:
POST /candidatos/{id}/submit
POST /candidatos/{id}/approve
POST /candidatos/{id}/decline
POST /candidatos/{id}/transfer
O resource candidatos
possui comportamentos distintos. O approve
pode, por exemplo, disparar um Evento que é capturado por outro sistema. Que por usa vez, vai disparar um e-mail para o RH.
O transfer
pode gerar um fluxo de aprovação com outro gestor para aceitar a transferência do candidato.
O REST nunca limitou o Resource a substantivos sem acões.
REST é sobre Resource
O artigo de Roy Fielding não especifica que a classificação de um Resource segue essas regras. Pelo contrário, o artigo menciona que um Resource é qualquer coisa que possa ser identificada.
A RFC 3986 vai de encontro ao artigo de Roy, resource é qualquer coisa que possa ser identificada através de uma URI.
This specification does not limit the scope of what might be a
resource; rather, the term "resource" is used in a general sense
for whatever might be identified by a URI. Familiar examples
include an electronic document, an image, a source of information
with a consistent purpose (e.g., "today's weather report for Los
Angeles"), a service (e.g., an HTTP-to-SMS gateway), and a
collection of other resources.
Uniform Resource Identifier (URI): Generic Syntax - RFC 3986
Logo uma ação é perfeitamente identificável. candidato/{id}/aprrove
é um resource único, identificável e com uma URI. Além disso ele deixa claro a ação que será feita em conjunto com os verbos HTTP.
Dicas e sugestões
Não há um guia oficial sobre as melhores praticas de projetar as APIs. Logo as sugestões abaixo estão baseadas em um consenso do que são boas práticas.
- Respeitar os verbos HTTP em primeiro lugar.
HTTP Method | Seguro | Semantica |
---|---|---|
OPTIONS | Sim | Busca os metodos http válidos e outras opções |
GET | Sim | Busca um resource |
HEAD | Sim | Busca apenas o header de um resource |
PUT | Não | Atualiza um resource |
POST | Não | Cria um resource |
DELETE | Não | Remove um resource |
PATCH | Não | Atualiza parcialmente um resource |
Utilizar ações apenas após definir uma URI para um resource, desde que a ação não sobrescreva o sentido do verbo HTTP, por exemplo, POST /usuarios/criar
. Neste caso basta o verbo HTTP, POST /usuarios
.
A ação deve estar ligado a um requisito de negócio. Deve ser clara, POST /usuarios/2/solicitar-ferias
. Esse tipo de cenário pode ser utilizado em conjunto com o CQRS. Na Controller o método pode esperar um objeto de tipo SolicitarFeriasCommand.
O time ganha liberdade para fazer design melhores, oferecendo recursos que não São baseados em CRUD. E sem ferir o padrão REST.
Conclusão
O REST é um conceito bem estabelecido no mercado. Infelizmente por uma falta de entendimento do conceito de Resource direciona times de desenvolvimento a perder horas de discussão sobre como prover um determinado serviço sem quebrar o padrão RESTFul.
Espero que tenha ajudado vocês!