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