Web Services REST
Bruno Pereira
Proprietary and Confidential
Agenda
Definição e um pouco de história
Motivação
Arquitetura
Implementação
Como refinar a implementação
Conclusão
Proprietary and Confidential
REST - Definição
REpresentational State Transfer
Termo proposto por Roy Fielding
Estilo de arquitetura
WS com arquitetura da internet
Exploração extensa do HTTP
Proprietary and Confidential
Um pouco de história
Final da década de 90:
Aplicações distribuídas com HTTP + XML
Implementações customizadas sempre
Protocolos próprios
Diferentes abordagens de segurança,
controle transacional, etc.
Desafio: Como vender middleware assim?
Proprietary and Confidential
Surgimento WS-*
Sem padrões, difícil vender middleware
Fabricantes padronizam implementações
WS-Addressing
WS-Security
SOAP
WSDL
UDDI
WS-Policy
Complexidade
Proprietary and Confidential
Surgimento REST
Tese Roy Fielding
Conjunto de regras simples
Grupos de estudo IETF
Especificações após uso maduro
Proprietary and Confidential
Analogia das evoluções
WS-*
Modelo OSI
Muitas specs antes das implementações
Modelo waterfall/cascata
REST
TCP/IP
Regras simples
Specs acompanham implementações
Modelo incremental
Scrum anyone??
Proprietary and Confidential
Motivação
Porque implementar serviços REST?
Protocolos menos complexos
Mais poder e flexibilidade
Arquitetura amplamente disponível
Menos overhead de protocolo
No Silver Bullet!
Proprietary and Confidential
Arquitetura dos web services REST
Proprietary and Confidential
Estilo de acesso aos serviços
Proprietary and Confidential
Estilo declarativo x imperativo
Método HTTP
URI do recurso
GET
/usuario/123456
Como
O quê
<soap:Envelope>
<soap:Body>
<globo:consultarUsuario>
<id>123456</id>
</globo:consultarUsuario>
fazerEstaOperacao
</soap:Body>
</soap:Envelope>
Proprietary and Confidential
Implementação de serviços REST
Proprietary and Confidential
Problema proposto
Leilão do Mercado Livre
Vendedor anuncia produto
Interessados realizam ofertas
Vendedor aceita melhor oferta
Vendedor e comprador se avaliam
Proprietary and Confidential
Serviços oferecidos
Anunciar item
Buscar ítens do vendedor
Cadastrar usuário
Realizar oferta
Retirar oferta
Buscar ofertas do item
Buscar melhor oferta
Aceitar melhor oferta
Avaliar usuário
Buscar avaliações do usuário
Proprietary and Confidential
Modelagem com recursos
Recursos identificados:
Usuário
Item (produto)
Oferta
Avaliação
Como manipular estes recursos?
Defina seu protocolo de comunicação REST
Proprietary and Confidential
Protocolo de comunicação REST
Perguntas importantes:
1. Quais são os recursos?
2. Quais são as URIs?
3. Quais são os formatos manipulados?
4. Que métodos HTTP são aceitos em cada URI?
5. Que status HTTP deve ser retornado em cada
situação?
6. Que cabeçalhos HTTP são relevantes em cada
situação?
Proprietary and Confidential
Protocolo de comunicação REST
GET, POST, PUT, DELETE
!=
SELECT, INSERT, UPDATE, DELETE
Quanto mais CRUD, mais fácil definir protocolo
REST é bem mais do que CRUD
REST envolve interações entre Recursos
Como modelar serviço de “Aceitar melhor oferta”?
Trivial com WS-*, não-trivial com REST
Paradigma diferente, modelagem diferente
Proprietary and Confidential
Protocolo de comunicação REST
Não posso usar PUT e DELETE,
que posso fazer??
1. Reclamar
2. POST com x-http-method-override
E se eu precisar enviar dados
em uma requisição sem corpo??
Mesma receita!
Proprietary and Confidential
Protocolo de comunicação REST
URI
/item/{id}
/item/{id}/ofertas
/oferta/{id}
/usuario
/usuario/{id}
/usuario/{id}/avaliacoes
/usuario/{id}/itens
/avaliacao/{id}
/avaliacao/de/{id}/para/{id}
Método
GET
PUT
GET
POST
GET
PUT
DELETE
POST
GET
PUT
GET
GET
POST
GET
POST
Com URI + método,
você é capaz de deduzir
qual é o serviço em
questão?
Proprietary and Confidential
Arquitetura da implementação
Servlet como FrontController
Uma classe processor por prefixo de URI
Proprietary and Confidential
Arquitetura da implementação
Papel do Controller:
Inicializa Processors
Valida URI + método HTTP
Encaminha requisição para processors
Papel do Processor:
Parsing de URIs para obter parâmetros
Parsing do corpo das requisições
Valida requisição
Acessa Service Layer e gera resposta
Proprietary and Confidential
Validação de URIs + método HTTP
Controller registra URIs/Processor
Processors anotam métodos com URI + método HTTP
Controller invoca método por reflexão
E se uma URI inválida foi invocada?
Status HTTP 400 – Bad Request
URI válida invocada com método HTTP inválido?
Status HTTP 405 – Method Not Allowed
Proprietary and Confidential
Parsing de URIs
Processor conhece URI de cada método
@Mapeamento(metodo = "GET", pattern = PATTERN_ITEM_EXISTENTE)
buscarItem(HttpServletRequest, HttpServletResponse)
{
String[] tokens = request.getPathInfo().split("/");
String id = tokens[2];
Item item = itemService.buscar(id);
Proprietary and Confidential
Parsing do corpo da requisição
Processor conhece formato esperado pelo método
Mapeamento Java/XML e XML/Java com XStream
E se o corpo da requisição veio inválido?
Status HTTP 400 – Bad Request
Como indicar o erro?
<erro>
<codigo>2319</codigo>
<mensagem>
Atributo XPTO é obrigatório
</mensagem>
</erro>
OU
<erros>
<erro>
<codigo>2319</codigo>
<mensagem>
Atributo XPTO é obrigatório
</mensagem>
</erro>
...
</erros>
Proprietary and Confidential
Clientes Java
Requisições HTTP com commons-http-client
Mapeamento Java/XML e XML/Java com XStream
Status HTTP é o mais importante
Alguns headers são importantes também
Proprietary and Confidential
Exemplo 1: Criação de Oferta
Cliente:
Obter usuário ofertante
Obter item desejado
Obter dados da oferta
Montar URI de ofertas do Item
Gerar corpo da requisição
Conferir resposta
Proprietary and Confidential
Exemplo 1: Criação de Oferta
Servidor:
Validar URI + método HTTP
Parsing da URI para obtenção do item
Parsing do corpo da requisição
Chamada ao Service Layer
Geração da resposta
Status HTTP da resposta
Header Location
Proprietary and Confidential
Exemplo 2: Avaliação de usuário
Cliente:
Obter usuário avaliador e o avaliado
Obter dados da avaliação
Montar URI da avaliação
Gerar corpo da requisição
Conferir resposta
Proprietary and Confidential
Exemplo 2: Avaliação de usuário
Servidor:
Validar URI + método HTTP
Parsing da URI para obtenção dos usuários
Parsing do corpo da requisição
Chamada ao Service Layer
Geração da resposta
Status HTTP da resposta
Header Location
RESTFul DSL
Proprietary and Confidential
Principais Status HTTP
Status
Utilização
200
Solicitação realizada com sucesso
201
Recurso criado com sucesso
400
Requisição inválida
404
Recurso inexistente
405
Método HTTP não permitido para a URI
500
Erro interno no servidor
Proprietary and Confidential
Como refinar a implementação
Proprietary and Confidential
Flexibilidade nas respostas
Me diga o
que queres
Seja feita
vossa vontade
Accept: text/xml,
application/json
<usuario>
<login>blpsilva</login>
</usuario>
<usuario>
<login>teste999</login>
</usuario>
OU
"usuarios":[
{
Uma interface,
"login":"blpsilva",
},
múltiplos formatos
{
"login":"teste999",
}
]
Proprietary and Confidential
Flexibilidade nas requisições
Me diga o que
estás mandando
Content-Type: text/xml;
charset=UTF-8
OU
Content-Type: application/json;
charset=ISO-8859-1
Uma interface,
múltiplos formatos!
Eu converto
e processo
Proprietary and Confidential
Flexibilidade nas requisições
Implementar esta flexibilidade é muito trabalhoso…
JSR-311/Jersey
Mas meus serviços são em Ruby/Php/Perl/Python…
Lots of fun for you!
Minha aplicação roda no Vignette, não tenho Java 5…
… é uma pena quando isso acontece!
Proprietary and Confidential
JSR-311/Jersey
URIs mapeadas em classes/métodos
Parâmetros extraídos das URIs
Conversões xml/json/etc -> Java
Conversões Java -> xml/json/etc
Manipulação de status/headers HTTP
Proprietary and Confidential
Dúvidas comuns
Como tratar a paginação de resultados?
Como implementar links entre recursos?
Como lidar com acessos concorrentes?
Como autenticar/autorizar operações?
Atom + AtomPub + Apache Abdera
Blueprint de implementação REST
Excelente para conteúdo web
Google, Microsoft E Globo.com já usam
Proprietary and Confidential
Conclusão
Web services antigamente:
Troca de performance por interoperabilidade
Web services atualmente:
Alta performance E interoperabilidade
Flexibilidade absoluta
Web services no futuro:
Forma padrão de comunicação entre aplicações?
REST everywhere
Proprietary and Confidential
Dúvidas??
Proprietary and Confidential
Quer conhecer mais?
Nas bancas: Java Magazine 56 – Abril/2008
Proprietary and Confidential
Contato
[email protected]
http://blpsilva.wordpress.com
Proprietary and Confidential