ReST
Restructured State Transfer
- Criado por Roy Fielding em 2000.
- Fielding trabalhou na definição do HTTP e no início do projeto Apache.
O que é ReST?
É uma "arquitetura" de transmissão de dados sobre HTTP.
("Conjunto de idéias para utilizar HTTP para geração de APIs.")
Linguagem? Qualquer!
- Python: Flask, Django, Flask-Restless, Django Rest Framework
- Ruby: Ruby on Rails, Sinatra
- Java: Spring, Restlet, Jersey
- C#: Ramone
- Nodejs: Express
- Rust: Rustful
ReST e HTTP
- Métodos HTTP = operação de banco de dados (CRUD).
- Resultado das operações são indicados por status HTTP.
- Meta-informações podem ser enviadas nos headers.
- Por exemplo, atenticação é feita por HTTP auth.
- Sem transações/sessões -- todas as operações são atômicas.
Em HTTP, usam-se métodos para descrever o que quer ser feito:
POST
requisita informações, com conteúdo.
GET
requisita informações, sem conteúdo.
(Ainda: PUT, DELETE, HEAD, TRACE, PATCH, OPTIONS)
Em ReST, métodos HTTP viram CRUD:
- Create ⇒ POST
- Retrieve ⇒ GET
- Update ⇒ PUT
- Delete ⇒ DELETE
- Update ⇒ PATCH
Recursos
- Em ReST, as "tabelas" são chamadas "recursos".
- Sempre substantivos no plural.
- Duas URLs por recurso
- Uma para o conjunto;
- Uma para elementos específicos.
URLs para o Recurso
GET /recurso/
⇒ retorna todos os elementos do recurso.
POST /recurso/
⇒ cria um novo elemento.
PUT /recurso/
⇒ atualização em massa.
DELETE /recurso/
⇒ remove todos os elementos do recurso.
URLs para o Elemento
GET /recurso/id
⇒ retorna as informações do elemento com identificador "id".
POST /recurso/id
⇒ proibído, use POST /recurso/
para criar elementos.
PUT /recurso/id
⇒ atualiza as informações do elemento.
DELETE /recurso/id
⇒ remove o elemento com identificador "id".
Exemplos
GET /users/
⇒ Retorna a lista de todos os usuários.
POST /users/
⇒ Cria um novo usuário.
GET /users/1
⇒ Retorna as informações do usuário com id "1".
PUT /users/1
⇒ Atualiza as informações do usuário "1".
DELETE /users/1
⇒ Remove o usuário "1".
Requisições sem recursos
Requisições sem um recurso definido utilizam um verbo e GET:
GET /convert/?source=BRL&value=10&target=AUD
Conteúdo
Formato das respostas/requisições
Qualquer formato, ReST não define um específico.
- XML
- JSON
- HTML (www-form-encoded)
- CNAB
Fica a cargo da equipe decidir o melhor formato para a aplicação.
Resultado das operações
São utilizados os status HTTP
- 200 OK ⇒ operação concluída com sucesso.
- 400 Bad Request ⇒ algo errado com a requisição.
- 401 Unauthorized ⇒ o usuário informado não tem permissão para acessar o recurso.
- 403 Forbidden ⇒ precisa de autenticação e essa não foi informada.
- 404 Not Found ⇒ recurso ou elemento não existe.
- 405 Method Not Allowed ⇒ metódo inválido para recurso/elemento (p.ex. "POST" num elemento)
E assim por diante...
Entretanto...
Problema
ReST não define o que fazer em caso de conflito dos erros.
Exemplo
Operação para adicionar um usuário à um grupo:
- 404 se o grupo não existir;
- Qual status a ser retornado quando o usuário não existe, neste caso?
Normalmente é enviado um corpo indicando o erro de forma mais completa,
ainda com status HTTP.
Por que usar ReST?
- Reaproveita toda a estrutura HTTP existente.
- HTTP praticamente padrão em todas as linguagens "na caixa".
- (E, se não tiver, o protocolo é simples o suficiente para uma
implementação na hora.)
- Dificilmente portas HTTP (80 e 443) são bloqueadas em proxies.
- "Sintaxe" simples.
Por que não usar ReST?
- Segurança depende de terceiros (HTTPS).
- Existem outras opções (OAuth, por exemplo), mas são complexas e não se parecem
com soluções HTTP.
- Não recomendado para dispositivos com processamento e memória
extremamente limitados.
- Necessidade de sessões/transações.
- Requisito não é um serviço.