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).
  • Status das operações são status HTTP.
  • Meta-informações podem ser enviadas nos headers.
    • 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 /covert/?source=BRL&value=10&target=AUD

Conteúdo

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.

Status

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...

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 junto com o erro.

Por que usar ReST?

  • Reaproveita toda a estrutura HTTP existente.
  • HTTP praticamente padrão em todas as linguagens na caixa.
  • Dificilmente portas HTTP (80 e 443) são bloequeadas 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.

Perguntas?