Você está na página 1de 20

Aplicando Web Services REST com a API JAX-RS

Rodrigo Arajo dos Santos Edigar A. Diniz Jnior Resumo Este artigo visa apresentar a tecnologia REST que representa uma alternativa ao desenvolvimento de Web Services SOAP. Ser apresentada tambm a API JAX-RS, que facilita o desenvolvimento de aplicaes REST que utilizam a linguagem Java. Adicionalmente, ser desenvolvida uma aplicao que demonstre como projetar uma aplicao REST com a linguagem Java e a API JAX-RS. Palavras-chave: REST, Web Services, API JAX-RS, SOAP, JAVA 1. Introduo Os Web Services surgiram como uma forma de comunicao entre aplicaes distribudas e heterogneas. Entretanto ao desenvolver uma aplicao que necessite disponibilizar Servios Web (citados neste artigo como Web Services), tem-se duas opes de implementao para tal tarefa. Os Web Services SOAP, que so uma evoluo das RPC's (Remote Procedure Calls) e os Web Services REST, que trabalham de forma semelhante a qual ns, seres humanos utilizamos a World Wide Web. Roy Fielding, o criador do REST apresenta a arquitetura REST como uma alternativa ao estilo RPC para a implementao de Servios Web. Este artigo pretende demonstrar os conceitos bsicos do REST discutindo as suas caractersticas tcnicas e demonstrar a sua utilizao por meio de um exemplo prtico. 2. O que REST Roy Fielding, o principal co-autor da especificao HTTP, em sua tese de doutorado, criou o termo REST (Representational State Transfer) que conforme sua definio, um estilo arquitetural para sistemas distribudos multimdia (Fielding, 2000). REST prope um conjunto de restries s arquiteturas Web. A adoo destas restries resultam em benefcios desejveis. Fielding rene uma srie de estilos arquiteturais pr-existentes utilizados em aplicaes Web a novas propostas para fundamentar este novo estilo arquitetural (Fielding, 2000). 3. Estilos Arquiteturais herdados pelo REST Nesta seo so descritos os estilos arquiteturais herdados pela arquitetura REST. 3.1. Arquitetura Cliente-Servidor REST utiliza a arquitetura Cliente-Servidor. Isto garante a separao de interesses e como benefcios podemos citar, a independncia das aplicaes clientes e servidoras, a portabilidade do cliente para mltiplas plataformas e a escalabilidade da aplicao servidora

(Fielding, 2000). 3.2. Falta de Estado (Stateless) Todos os dados necessrios ao processamento de uma requisio, devero ser informados atravs da URI. Desta forma, o servidor no necessitar manter as informaes das requisies anteriores e caber a aplicao cliente manter o seu prprio estado de sesso (Richardson; Ruby, 2007). Como benefcios da falta de estado, podemos citar: Melhoria da confiabilidade: Se um cliente fizer uma requisio e algum eventual erro ocorrer, ele necessitar apenas reenviar a requisio (Richardson; Ruby, 2007). Escalabilidade de uma aplicao: Uma vez que uma requisio independe de outras, vrios servidores podem servir a mesma aplicao atravs de balanceamento de carga1 sem a necessidade de se coordenarem (Richardson; Ruby, 2007).

Entretanto, como desvantagem podemos citar a perca de performance de rede devido ao envio repetitivo dos mesmos dados a cada requisio (Fielding, 2000). 3.3. Cache Permite que dados possam ser reutilizados, com a finalidade de economizar a utilizao dos recursos de rede. Clientes e componentes intermedirios podem armazenar cpias de mdias marcadas com o cabealho cacheable2 e estas cpias podem substituir requisies a aplicao servidora (Fielding, 2000). 4. Princpios do REST Adicionalmente aos estilos arquiteturais pr-existentes adotados, Fielding criou novos princpios, recomendados aplicaes Web. 4.1. Recursos Segundo a especificao do protocolo HTTP (verso 1.1), Um recurso um objeto ou servio que pode ser identificado atravs de uma URI. (Fielding et al, 1999). 4.2. Identificao dos Recursos atravs de URI Se uma parte das informaes no tiver uma URI, no ser um recurso, e realmente, no estar na web (Richardson; Ruby, 2007). A URI tem a atribuio de identificar e localizar um recurso globalmente. Desta forma, ao ser identificado por uma URI, um recurso pode ser acessado remotamente em qualquer local do mundo. 4.3. Manipulao dos Recursos atravs de representaes Os recursos so dissociados de suas representaes para que seu contedo
1 Balanceamento de Carga: Diversas mquinas ligadas em rede e que em conjunto servem uma aplicao dividindo a carga de processamento requisitada. 2 Cacheable: Cabealho HTTP que informa se um dado pode possuir cpias temporrias remotas que podem substituir o dado original.

possa ser acessado em uma variedade de formatos (tais como HTML, XML, texto puro, PDF, JPEG e outros). (Pautasso et al, 2008). Um recurso no um dado, mas sim a informao que um dado representa. Uma informao pode ser disponibilizada em diversos formatos de dados diferentes. Por exemplo, uma cidade pode ser representada na forma de uma imagem de satlite, ou em na forma de um arquivo XML que armazena suas principais caractersticas geogrficas.

Figura 01. Demonstrao das representaes de um recurso cidade.

Um recurso manipulado atravs de suas representaes, pois no h como manipular uma idia, um conceito. Para criar um novo recurso, o cliente envia uma representao deste aplicao servidora. necessrio que esta representao seja de um tipo suportado pelo servidor. Da mesma forma, para alterar um recurso, o cliente recupera uma representao, a altera e em seguida a envia novamente ao servidor. 4.4. Interface Uniforme Ao aplicar o princpio da engenharia de software de generalidade para a interface de componentes, a arquitetura geral do sistema simplificado e da visibilidade das interaes melhorada. (Fielding, 2000). Os recursos so dissociados das aes que os manipulam, desta forma, todos os recursos so manipulados atravs das mesmas aes. Estas aes so um pequeno e bem definido conjunto de mtodos. Ao disponibilizar seus servios atravs de uma interface uniforme, a aplicao ganha em: Acessibilidade: Uma vez que possua a URI de um recurso, um cliente saber manipul-lo (Richardson; Ruby, 2007). Comparativamente, caso este mesmo servio seja disponibilizado atravs de uma RPC, sua interface seria especfica e isto faria com que o cliente necessitasse aprender como utiliz-la (como cada servio recebe e envia dados). Economia de recursos de rede: Suas mensagens no necessitam conter meta-dados que informem dados sobre a interface utilizada (Richardson; Ruby, 2007). Performance: Possibilita a manipulao das mensagens de requisio e resposta pelos componentes intermedirios, caracterstica que faz com que servios REST melhor se adequem infra-estrutura de rede da internet. (Fielding, 2000) Em sua tese, Fielding no restringe o REST ao protocolo HTTP, entretanto ele afirma ser este o nico protocolo especificamente projetado para fornecer suporte a este estilo arquitetural. REST tambm no define quais so os mtodos que esta interface deve possuir, mas ao adotar o HTTP, os mtodos utilizados so aqueles definidos neste protocolo.

Figura 02. Demonstrao comparativa entre uma interface especfica e outra uniforme. (SILVA, 2008).

Alguns autores (como Pautasso et. al.) tentam mapear cada mtodo HTTP para uma operao CRUD3, entretanto existem mtodos HTTP que realizam mais de uma operao CRUD. A tabela abaixo demonstra a utilizao destes mtodos. Operao CRUD Consultar Excluir Incluir Mtodo HTTP Get Delete Put Post Put Post Definio Recupera a representao de um Recurso. Remove um Recurso. Cria um recurso, a URL definida pelo cliente. Cria um recurso subordinado. A URL definida pelo servidor e o mtodo utilizado no recurso superior ao qual ser criado. Sobrescreve um recurso. Altera o recurso, sem sobrescrever os dados j existentes do recurso.
Tabela 01 (Richardson; Ruby, 2007)

Alterar

Os mtodos Get e Delete possuem uma nica finalidade. O mtodo Put pode criar um novo recurso, ou sobrescrever um j existente. O mtodo Post possui diversas funes: Cria um novo recurso subordinado: Recursos que no podem ter a sua URI definida pelo cliente podem ser criados enviando sua representao em uma requisio POST a ao seu recurso pai. Nesta ocasio, o recurso pai considerado um recurso-fbrica, pois atravs deste que so criados novos recursos subordinados a este (Richardson; Ruby, 2007). Como exemplo desta situao, podem-se citar recursos que ao serem criados so persistidos em um banco de dados, e em sua URI seja informado o registro deste recurso. Altera um recurso alterando seu estado, sem sobrescrev-lo e sem alterar os dados prexistentes.. Fornece um bloco de dados para um processo de tratamento de dados. Entenda bloco de dados como um formulrio HTTP e processo de tratamento de dados como uma ao qualquer a ser executada no servidor (Richardson; Ruby, 2007). Esta forma de utilizao do mtodo Post desaconselhada em uma arquitetura REST, uma vez que rompe os princpios de uma interface uniforme permitindo com que vrios mtodos
3 CRUD: Acrnimo de Create, Read, Update, Delete (Criar, Ler, Atualizar e Excluir)

especficos sejam criados para um recurso (Richardson; Ruby, 2007). O protocolo HTTP tambm fornece dois mtodos utilitrios, o mtodo Head que utilizado quando se necessita obter apenas os meta-dados de um recurso (atravs de uma resposta com corpo vazio e com os mesmos cabealhos que seriam retornados a uma requisio do tipo Get) muito til quando se necessita apenas obter os meta-dados de um recurso que possui uma representao extensa e o mtodo Options que informa quais mtodos HTTP um recurso est habilitado a responder (atravs de uma resposta sem contedo e com o cabealho Allow) (Richardson; Ruby, 2007). 4.5. Mensagens Auto-Descritivas REST utiliza mensagens para trocar dados entre cliente e servidor, na prtica estas mensagens so requisies e respostas HTTP. Estas mensagens fornecem meta-dados contendo informaes relevantes aos clientes, servidores e componentes intermedirios (Roteadores) (Fielding, 2000). Estes meta-dados so dissociados do contedo da mensagem, desta forma, dados necessrios transmisso desta mensagem ficam disponveis aos componentes intermedirios e podem ser utilizados por exemplo para controlar cache, detectar erros de transmisso, negociar a representao apropriada e executar autenticao e controle de acesso (Pautasso, 2008). 4.6. Estado da Aplicao e Estado do Recurso Como visto na seo 1.1.2. REST so aplicaes sem estado (stateless). Isto quer dizer que dados relativos s sesses dos clientes (Estados da aplicao) devem ser mantidos no cliente. Entretanto, os dados relativos aos recursos (Estados do Recurso), estes sim devem ser mantidos no servidor (Richardson; Ruby, 2007). Assim como um usurio pode salvar um link de um site, uma aplicao cliente pode armazenar o link de um recurso, e utiliz-lo posteriormente. Isto possvel devido ao estado do recurso que mantido pelo servidor, desta forma possibilitando sua manipulao em um perodo posterior. Sendo assim, dados que necessitam ser mantidos por mais de um ciclo de uma requisio, devem se tornar recursos (Richardson; Ruby, 2007). 4.7. Hipermdia como o motor de estado da aplicao O servidor no responsvel por manter o estado da aplicao, entretanto ele pode guiar o cliente fornecendo os prximos passos que este poder seguir (Richardson; Ruby, 2007). Isto feito atravs de links contidos nos recursos requisitados. Cabe ento ao cliente escolher dentre os links fornecidos. Da mesma forma que acontece com um usurio que navega pelas pginas de um site, uma aplicao cliente navega por uma aplicao REST. Como exemplo disto, podemos citar uma consulta de cidades que pode retornar um XML contendo uma lista de cidades, e para cada cidade, poder ser informado apenas o seu nome e o seu link (tornando-se desnecessrio enviar os dados de todas as cidades, o que resulta em economia dos recursos de rede). Em seguida, para editar os dados de uma determinada cidade, o cliente ento utiliza o seu link, de forma a obter um novo XML contendo os dados desta cidade, em seguida, editando este XML e o reenviando ao servidor em uma requisio Put. 5. JAX-RS

Visando facilitar o desenvolvimento de servios REST, a comunidade Java atravs de um Java Community Process (JCP) desenvolveu a especificao JSR-311 (Java Specification Request 311) tambm conhecida como JAX-RS (Java API for RESTful Web Services) (Hadley; Sandoz, 2008). Esta especificao tem como objetivos: Desenvolvimento baseado em POJOs: Classes java sero POJOs disponibilizados como recursos atravs da utilizao de anotaes (Hadley; Sandoz, 2008). Centrado no HTTP: Conceitualmente REST no se restringe a este protocolo, porm este o nico protocolo existente para este estilo arquitetural (Hadley; Sandoz, 2008). Independncia de formato: Um recurso poder ser disponibilizado atravs de diversas representaes sem codificao adicional (Hadley; Sandoz, 2008). Independncia de continer: Uma aplicao JAX-RS dever ser portvel a qualquer continer JEE (Hadley; Sandoz, 2008). Incluso no Java EE 6 (Hadley; Sandoz, 2008).

5.1. Classes Recursos Utilizando JAX-RS um recurso web implementado como uma classe recurso e as requisies processadas por mtodos recursos. (Hadley; Sandoz, 2008). Ou seja, com a JAX-RS possvel criar uma aplicao REST definindo classes que iro agir como recursos. 5.1.1. Definindo a URI de um Recurso Em JAX-RS a URI de um recurso comea a ser construda com o contexto da aplicao. Opcionalmente, um diretrio lgico (ou caminho) pode ser definido especificamente para agrupar todos os recursos JAX-RS. Em seguida vem o caminho do recurso raiz, depois os caminhos dos possveis sub-recursos. Ao final da URI, podero ser opcionalmente informados os parmetros de matriz e os parmetros de consulta. contexto da aplicao + diretrio dos recursos + recursos + parmetros http://localhost:8080/fretesRest/servicos/recursoraiz/sub1/sub2?paramConsulta=true
Listagem 01.

A parte da URI que forma o contexto da aplicao construda pelo host, porta e nome da aplicao, o diretrio dos recursos, informado no descritor de implantao web.xml. O restante da URI construdo nas classes e mtodos recursos atravs da anotao @Path. 5.1.2. Classe Recurso raiz Para que uma classe se torne um recurso-raiz basta a esta ser anotada com @Path e no argumento desta anotao ser definido um prefixo URI para este recurso conforme a listagem abaixo.
01 02 @Path(/recurso_raiz) public class RecursoRaiz() { //... }

Listagem 02.

5.1.3. Ciclo de vida de uma Classe Recurso Por padro, uma nova instncia de uma classe recurso criada para cada requisio. (Hadley; Sandoz, 2008). Em outras palavras, para cada requisio ser instanciada uma nova classe recurso e aps o envio da resposta, esta instncia ento ficar disponvel para ser destruda pelo Garbage Collector. Porm, as implementaes dessa especificao podero definir novos ciclos de vida para as classes recurso. A implementao de Referncia Jersey, disponibiliza dois novos escopos atravs das anotaes @PerSession (uma classe recurso por sesso) e @Singleton. (uma classe recurso para toda a aplicao) (Sun Microsystems, 2009). 5.2. Mtodos Recurso Mtodos Recursos so responsveis por responder requisies enviadas a uma Classe Recurso. Para que um mtodo se torne um Mtodo Recurso, deve se informar quais mtodos HTTP este mtodo estar designado a responder (Hadley; Sandoz, 2008). JAX-RS define um conjunto de anotaes que representam os mtodos HTTP. So elas: @GET, @PUT, @DELETE, @POST, @HEADER e @OPTIONS. A listagem abaixo demonstra um Mtodo Recurso que ir responder a requisies Put enviadas sua classe recurso.
01 02 03 04 05 06 07 08 @Path(/recurso_raiz) public class RecursoRaiz() { @PUT public void metodoRecurso(){ //... } }

Listagem 03. Exemplo de uma Classe Recurso que possui um Mtodo Recurso.

Caso no exista um mtodo explicitamente designado a receber requisies para os mtodos Head e Options, JAX-RS ir lhes fornecer suporte automtico. Para requisies do tipo Options, a implementao JAX-RS ir retornar uma resposta com base nas informaes sobre os recursos disponveis e para as requisies do tipo Header, caso haja um mtodo designado a receber requisies do tipo Get, este tambm ir responder suas requisies. Porm, se um mtodo Get possuir uma lgica complexa para construir o corpo da resposta, designar um mtodo exclusivamente para atender as requisies do tipo Head ir fornecer uma melhoria no desempenho para as requisies deste tipo, uma vez que este mtodo ser projetado para retornar apenas os meta-dados do seu Recurso. 5.2.1. Parmetros Os parmetros de um mtodo recurso podem ser utilizados para receber dados do cliente, estes dados podem ser extrados da requisio atravs da URI, dos cabealhos de requisio ou de cookies. Segue abaixo, a lista das anotaes utilizadas em parmetros de forma a definir que estes iro receber estes dados. Anotao @PathParam @MatrixParam Descrio Extrai o valor de um parmetro localizado no padro da URI. Extrai o valor de um parmetro de matriz da URI.

@QueryParam @HeaderParam @CookieParam

Extrai o valor de um parmetro de consulta da URI. Extrai o valor de um cabealho HTTP. Extrai o valor de um cookie.
Tabela 02 (Hadley; Sandoz, 2008)

Um Mtodo Recurso poder possuir apenas um parmetro que no utilize nenhuma das anotaes citadas na tabela acima, pois este parmetro no anotado ser o responsvel por receber o contedo da requisio. A tabela abaixo demonstra um Mtodo Recurso que possui dois parmetros, um receber uma varivel de consulta e o outro o contedo da requisio.
01 02 03 04 05 06 07 08 @Path(/recurso_raiz) public class RecursoRaiz() { @PUT public String metodoRecurso(@QueryParam(param) String param, String conteudo){ //... } }

Listagem 04. Exemplo de um Mtodo Recurso que receber um parmetro de consulta e um contedo.

5.2.2. Retornos JAX-RS fornece um mapeamento entre os tipos Java que um mtodo recurso pode retornar e os tipos de contedo da resposta HTTP. Este mapeamento realizado pela implementao JAX-RS que utiliza classes denominadas Provedores de Entidade. Estas classes sero descritas na seo 5.7. Os tipos retornados podero ser void, Response ou qualquer outra classe Java. Basicamente, para um mtodo que retorne void ou null, ser gerada uma resposta com corpo vazio (e mensagem de status nmero 204 no content). Um mtodo que retorne um objeto java por padro ir retornar uma resposta com o contedo deste objeto, e mensagem de status nmero 200 (status ok) (Hadley; Sandoz, 2008). Caso o desenvolvedor necessite retornar uma resposta personalizada, como por exemplo, informar uma mensagem de status diferente, adicionar novos cabealhos ou cookies, este poder retornar um objeto do tipo Response (Silva; Buback, 2008). 5.3. Sub-Recursos Sub-Recursos so representados por Mtodos Recurso. Um Mtodo Recurso poder implementar o Sub-Recurso, ou poder alocar uma outra Classe Recurso correspondente a este Sub-Recurso (Hadley; Sandoz, 2008). Em ambos os casos, o mtodo em questo dever ser anotado com @Path para se definir o prefixo URI que identifica o SubRecurso. O mtodo que implementa o Sub-Recurso denominado Mtodo Sub-Recurso (listagem 00). J o mtodo que localiza um recurso correspondente denominado Alocador de Sub-Recurso (listagem 00). Mais precisamente, o alocador de sub-recurso dever retornar a instncia de uma classe recurso.

01 02 03 04 05 06 07 08

@Path(/recurso_raiz) public class RecursoRaiz() { @GET @Path(/metodo_sub_recurso) public void metodoSubRecurso(){ //... } }

Listagem 05. Exemplo de um Mtodo Sub-Recurso


01 02 03 04 05 06 07 08 @Path(/recurso_raiz) public class RecursoRaiz() { @GET @Path(/metodo_alocador_sub_recurso) public RecursoAlocado metodoAlocadorSubRecurso(){ return new RecursoAlocado(); } }

Listagem 06. Exemplo de um Mtodo Alocador de Sub-Recurso

5.4. Padres de URI Em um padro de URI, podemos definir parmetros, estes parmetros consistem em um nome contido em um par de chaves. Adicionalmente, podemos definir uma expresso regular que dever ser atendida, para que a requisio seja vlida. Por exemplo, se um parmetro for definido para receber um valor numrico, podemos definir uma expresso regular que aceite apenas dgitos numricos para este parmetro. Caso a URI da requisio no atenda a esta regra a requisio ser invlida.
01 02 03 04 @Path(/cidade/{id} : [0-9]+) public String testeRegex(@PathParam(cidade) String idade){ return Idade = + idade; }

Listagem 07. Exemplo da definio de um padro de URI.

5.5. Tipos de mdias Um dos objetivos da JAX-RS define que um recurso poder ser disponibilizado em diversos formatos de mdia sem que para isto, o desenvolvedor tenha que escrever cdigo extra para fornecer esta flexibilidade. Caber ao desenvolvedor apenas designar ao recurso quais formatos este poder produzir ou consumir. Esta designao realizada atravs das anotaes @Produces e @Consumes onde em seus parmetros dever ser passada a lista de tipos de mdia (conhecidos pela especificao do protocolo HTTP como cdigos media-type) que identificam os formatos desejados. Por padro, um recurso que no possua a informao de quais tipos de mdia pode consumir ou produzir, receber o tipo genrico */*, dessa forma, aceitando qualquer tipo de mdia. A informao sobre quais mdias uma requisio pode enviar, ou espera receber fornecida pelos seus cabealhos Accept header e Content-Type respectivamente. Ao especificar quais tipos de mdia um recurso poder consumir ou produzir, qualquer requisio que no atender a esta regra, no ir ser processada por este recurso. 5.6. Provedores

A seo anterior demonstrou como so definidas as representaes de tipos de formato que um recurso poder consumir e produzir e que caber a implementao JAX-RS fazer a converso entre os objetos Java e os corpos das requisies. A tarefa de realizar esta converso atribuda classes denominadas provedores de entidade. JAX-RS define que suas implementaes forneam provedores de entidade para os tipos Java abaixo: Tipos de Mdia Todos os tipos de mdia (*/*) Todos os tipos de mdia de texto (text/*) Todos os tipos de mdia (*/*) Todos os tipos de mdia (*/*) Todos os tipos de mdia (*/*) Todos os tipos de mdia (*/*) Todos os tipos de mdia (*/*) Todos os tipos de mdia (*/*) Tipos XML (text/xml, application/xml e application/*+xml) Contedo de formulrio (application/x-www-form-urlencoded) byte[] java.lang.String java.io.InputStream java.io.Reader java.io.File javax.activation.DataSource StreamingOutput javax.xml.transform.Source javax.xml.bind.JAXBElement e classes JAXB de aplicao. MultivaluedMap<String, String> Tipos Java

Tabela 03 Mapeamento entre Tipos Java e Tipos de mdia (Hadley; Sandoz, 2008).

Desta forma, caso seja necessrio utilizar um tipo java diferente dos citados acima, dever ser construdo um novo provedor de entidade para este tipo. Todo provedor de entidade deve ser decorado com a anotao @Provider e implementar ao menos uma destas duas interfaces: MessageBodyReader (que realiza a converso do corpo da requisio para o tipo Java) e MessageBodyWriter (que realiza a converso do tipo Java para o corpo da resposta).
01 02 03 04 05 @Provider public class ProvedorTeste implements MessageBodyHeader<ClasseASerConvertida>{ // ... cdigo de converso }

Listagem 08. Demonstrao de um Provedor.de contedo.

5.7. Contextos possvel obter informaes do contexto da aplicao e das requisies individuais. A especificao JAX-RS fornece um conjunto de classes responsveis por representar estas informaes. Estas classes so denominadas classes contexto. Instncias destas classes so fornecidas pela implementao JAX-RS atravs da anotao @Context, que pode ser utilizada em recursos(em atributos da classe e em

parmetros dos mtodos) e em provedores de entidade, conforme o exemplo abaixo.


01 02 03 public String teste(@Context UriInfo uriInfo){ // ... }

Listagem 08. Exemplo da utilizao de uma classe contexto.

Segue abaixo a lista de classes de contexto: Classe UriInfo HttpHeaders Request Descrio Obtm informaes da URI, como parmetros de consulta e URI absoluta. Obtm informaes dos cabealhos e cookies. Obtm informaes sobre a requisio

SecurityContext Obtm informaes de segurana fornecida atravs de JAAS (Java Authorization and Authentication Security) como o tipo de autenticao e usurio principal. Providers 5.8. Excees Por padro, ao ocorrer uma exceo em um Mtodo Recurso uma resposta com cdigo de status 500 (Erro interno no servidor) enviada ao cliente. Entretanto, caso o desenvolvedor necessite retornar uma exceo com status diferente este pode faze-lo lanando uma exceo javax.ws.rs.WebApplicationException definida na API JAX-RS. A listagem abaixo demonstra a utilizao desta exceo:
01 02 03 04 05 06 try{ // ... catch(Exception e){ throw new WebApplicationException(e, 404);// informando status da resposta }

Obtm um provedor de contedo da aplicao.


Tabela 04. Lista de Classes Contexto

Listagem 09

6. Desenvolvendo um Web Service REST - Provedor de servio REST Nesta seo, ser desenvolvida uma aplicao que ir disponibilizar alguns servios para uma empresa de Fretes. Este exemplo visa demonstrar o uso prtico dos conceitos descritos neste artigo. Inicialmente sero apresentados os requisitos, logo em seguida ser demonstrada uma forma de se projetar os seus recursos. Esta aplicao ser implementada utilizando a linguagem Java e a API JAX-RS. 6.1 Requisitos Uma empresa especializada em realizar fretes entre empresas deseja disponibilizar servios para que softwares de seus clientes possam obter os preos, os tempos estimados e agendar fretes. Segue abaixo, a lista dos requisitos previstos para esta aplicao: N Servios Descrio Permite a uma empresa obter a referncia a outra. Informando a empresa destino, o peso da mercadoria e a data de envio, a empresa origem poder obter o preo e o tempo estimado deste frete. Permite a empresa origem agendar um frete, ser necessrio informar a empresa destino, a data de envio e o peso da mercadoria. Permite que um frete seja alterado ou excludo. Permite que um frete seja excludo.
Tabela 05 Servios Previstos para a aplicao.

01 Consultar Empresa. 02 Buscar preo e tempo estimado de um frete.

03 Agendar um frete 04 Editar um frete 05 Cancelar um frete 6.2. Projeto de recursos

Em sua obra Web Services RESTful (2007), os autores Leonard Richardson e Sam Ruby sugerem um procedimento para o projeto de Recursos constitudo por uma sequncia de etapas, este procedimento ser descrito logo abaixo. 1. Descobrir o conjunto de dados 2. Dividir o conjunto de dados em recursos Para cada tipo de recurso: 3. 4. 5. 6. 7. 8. 9. Nomear os recursos com URI's Exibir um subconjunto da interface Uniforme Construir a(s) representaes aceitas do cliente Construir a(s) representaes fornecidas pelo cliente Integrar este recurso aos recursos existentes, usando links e formulrios de hipermdia Considerar o curso tpico dos eventos: o que deve acontecer? Considerar as condies de erro: o que pode dar errado? As sees posteriores visam demonstrar a aplicao deste procedimento.

6.2.1 Descobrir o conjunto de dados Nesta etapa, busca-se realizar um levantamento dos tipos de dados que sero exibidos e manipulados pelos clientes (Richardson; Ruby, 2007). A aplicao de exemplo visa disponibilizar informaes sobre empresas e fretes. 6.2.2 Dividir o conjunto de dados em recursos Um servio web REST exibe seus dados e seus algoritmos atravs de recursos. (Richardson; Ruby, 2007). Para organizar os conjuntos de dados e as funcionalidades na forma de recursos, Richardson e Ruby (2007) proporam uma forma de se classificar os recursos: Recursos que representam dados: As instncias dos tipos de dados definidos na seo anterior so consideradas recursos deste tipo. Recursos que representam funcionalidades: Quando um recurso necessita expor uma funcionalidade que no se enquadra na interface uniforme, esta funcionalidade convertida em um sub-recurso. Recursos predefinidos: So recursos de alto nvel hierrquico e permanentes que servem para agrupar sub-recursos. Para a aplicao de exemplo, para cada tipo de dado definido na seo anterior, ser criado um recurso pr-definido que ser responsvel por agrupar todas as instncias deste tipo e todas as funcionalidades aplicadas a este tipo de dado que no se enquadram na interface uniforme. A tabela abaixo apresenta os recursos definidos: Recursos Pr-definidos Empresas Fretes Recurso nico que agrupar recursos do tipo empresa. Recurso nico que agrupar recursos do tipo frete e funcionalidades no vinculadas a um frete existente. Recursos que representam dados Empresa Frete Existir um recurso deste para cada instncia de empresa. Existir um recurso deste para cada instncia de frete. Recursos que representam funcionalidades Cotao Recurso que representa a funcionalidade de calcular o preo e o tempo estimado (em dias corridos) de um frete.
Tabela 06 Recursos definidos.

6.2.3. Nomear os recursos com URI's Definidos os recursos, deve-se ento criar o padro de suas URIs. Uma boa estratgia para a construo das URI's comear definindo os Recursos-Razes. Para a aplicao de exemplo, os recursos pr-definidos (Fretes e Empresas) sero definidos como Recursos-Razes. Quanto aos recursos que representam dados (recursos dos tipos frete e empresa) e aos recursos que representam funcionalidades (Cotao) sero subordinados aos recurso pr-definidos citados acima.

Ser adotado que no existir letras maisculas nas URI's desta aplicao. E que os recursos que representam dados sero identificados pelo padro: /<Tipo>s/{id}, onde id ser uma varivel de Path que informar o nmero identificador desta instncia. A tabela abaixo demonstra o padro das URI's definido para a aplicao de exemplo: N 1 1.1 2 2.1 2.2 Padro da URI /empresas /{id} /fretes /{id} /cotacao Objetivos Lista recursos do tipo empresa. Representa um recurso do tipo empresa j cadastrado. Lista recursos do tipo frete. Recurso-fbrica4 para recursos do tipo frete. Representa um recurso do tipo frete j cadastrado. Informa o preo e o tempo estimado de um frete.

Tabela 07 Definio dos padres de URI's.

6.2.4. Exibir um subconjunto da interface Uniforme Nesta etapa, so definidos quais mtodos HTTP cada recurso estar habilitado a responder (Richardson; Ruby, 2007). As empresas sero apenas consultadas e os fretes podero ser includos, alterados, excludos e consultados. O Recurso que representam funcionalidades (cotacao) ser consultado. Aplicando as consideraes da seo 4.4 aplicao de exemplo, pode-se definir que todos os recursos que necessitem ser consultados respondero ao mtodo Get e os recursos que puderem ser excludos tero seu mtodo Delete habilitado. J as operaes de incluso e alterao necessitam ser especificados para cada recurso. Como somente os Recursos do tipo frete devero possuir estas aes, para incluir ser utilizado o mtodo Post no recurso pr-definido fretes, pois ser a aplicao servidora a responsvel por criar a URI de cada novo recurso deste tipo. Para alterar ser utilizado o mtodo Put pois h a necessidade de se alterar os dados j informados nestes recursos. A tabela abaixo demonstra quais mtodos sero disponibilizados para cada recurso e adicionalmente informa quais os parmetros de consulta podero ser utilizados: N 1 1.1 2 2.1 Padro da URI /empresas /{id} /fretes /{id} Mtodos Get Get Get Post Get Delete Operao CRUD Consultar Consultar Consultar Incluir (um Frete) Consultar Excluir Parmetros de consulta nome, cidade origem, destino, dataenvio, peso, dataenvioinicio, dataenviofim -

4 Recurso-Fbrica: Um recurso que tem o seu mtodo Post utilizado para criar novos recursos subordinados. Mais detalhes na seo 4.4.

Put 2.2 /cotacao Get

Alterar Consultar

origem, destino, dataenvio, peso

Tabela 08 Definio dos padres de URI's.

6.2.5. Construir as representaes aceitas do cliente O objetivo desta etapa definir os dados a serem informados no corpo das respostas enviadas ao cliente e em quais formatos estes dados podero estar (Richardson; Ruby, 2007). Para a aplicao de exemplo, as representaes sero disponibilizadas nos formatos: XML e JSON. JAX-RS faz uso da API JAXB para realizar o processo de converso entre objetos Java e arquivos XML (Sun Microsystems Inc., 2009), bastando ao desenvolvedor final apenas realizar o mapeamento entre estes dois artefatos atravs de anotaes fornecidas por esta API. Estas anotaes so utilizadas na classe Java a ser convertida. Estas classes mapeadas, podem ser utilizadas nos Mtodos-Recursos, em seus parmetros ou em seus tipos de retorno. Entretanto, classes provedoras podem ser escritas para utilizar as anotaes JAXB para fornecer representaes em outros formatos, a implementao Jersey possui provedores5 para arquivos JSON. Para a aplicao de exemplo, sero criadas as classes listadas na tabela abaixo: Classe Java
@XmlRootElement(name="empresa") public class Empresa { private Integer id; private URI uri; private String nome; @XmlAtribute public Integer getId(){//...} @XmlAtribute public URI getUri(){//...} // Gets e Sets omitidos } @XmlRootElement(name="frete") public class Frete{ private private private private private private Long id; URI uri; Double peso; Date data; Empresa origem; Empresa destino;

Estrutura do XML

<empresa id="1" uri="http://fretes.com/empresas/01"> <nome>1</nome> </empresa>

@XmlAtribute public Integer getId(){//...} @XmlAtribute public URI getUri(){//...} // Gets e Sets omitidos } @XmlRootElement(name="cotacao") public class Cotacao{

<frete id="1" uri="http://frete.com/fretes/01"> <data>2009/10/01</data> <destino id="2" uri="http://frete.com/empresas/02"> <nome>Empresa 2</nome> </destino> <origem id="1" uri="http://frete.com/empresas/01"> <nome>Empresa 1</nome> </origem> <peso>1</peso> </frete>

<cotacao>

5 Classes Provedoras so descritas na seo 5.6.

private Double preco; private Date dataenvio; private Integer tempoestimado; // Gets e Sets omitidos }

<dataenvio>2009/10/28</dataenvio> <preco>176.00</preco> <tempoestimado>3</tempoestimado> </cotacao>

Tabela 09 Beans mapeados com as anotaes da API JAXB, permitindo com que instncias dessas classes possam ser convertidas em arquivos XML.

A anotao @Produces (ver seo 5.5 Tipos de mdia) ser utilizada nas Classes Recurso para informar os formatos de arquivos que podero ser retornados nas mensagens de respostas. A listagem abaixo demostra a sua utilizao:
01 02 @Produces({"application/xml", "application/json"}) public class FretesRecurso{ // ... }

Listagem 10

6.2.6. Construir as representaes fornecidas pelo cliente Esta etapa semelhante a anterior, porm nesta so definidas as representaes que podero ser fornecidas pelo cliente, em outras palavras, os dados existentes nos contedos das requisies dos clientes e em quais formatos podero ser escritos (Richardson; Ruby, 2007). Para todos os recursos da aplicao de exemplo, as representaes fornecidas pelos clientes podero ser dos tipos: XML e JSON. Apenas os recursos do tipo frete sero fornecidos pelo cliente no momento da incluso e da alterao. Conforme demonstrado na seo 5.5 (tipos de mdias), ao utilizar a API JAX-RS, as Casses-Recurso e Mtodos-Recurso utilizam a anotao @Consumes para informar os formatos de arquivos aceitos conforme demonstrado na listagem abaixo:
01 02 @Consumes({"application/xml", "application/json"}) public class FretesRecurso{ // ... }

Listagem 11

6.2.7. Integrar este recurso aos recursos existentes, usando links e formulrios de hipermdia As representaes dos recursos podem apresentar links para os recursos com os quais se relaciona. Isto permite com que a aplicao cliente possa navegar pelos recursos como acontece com a web humana (Richardson; Ruby, 2007). Em nossa aplicao, a representao de um frete no formato XML ir conter links para as empresas de origem e destino (conforme demonstrado nos arquivos XML de exemplo demonstrados na tabela 09). 6.2.8. Considerar o curso tpico dos eventos: o que deve acontecer? Nesta etapa define-se os processamentos que devero ocorrer para as requisies. Para a aplicao de exemplo, espera-se que o estado dos recursos dos tipos fretes e empresas sejam persistidos em um banco de dados. Para acessar o banco de dados ser utilizado o padro de projeto DAO (Data Acess Object Objeto de acesso aos dados). O diagrama de sequncia abaixo demonstra a interao realizada ao consultar recursos do tipo empresa.

Figura 03. Diagrama de sequncia demonstrando a iterao realizada ao recuperar a representao em XML do recurso Empresas.

6.2.9. Considerar as condies de erro: o que pode dar errado? Nesta ltima etapa, o desenvolvedor necessita implementar o tratamento para os possveis erros que podero ocorrer, como por exemplo uma requisio invlida (Richardson; Ruby, 2007). Para a aplicao de exemplo, podemos restringir que as variveis de caminho id dos recursos dos tipos Frete e Empresa sejam formados apenas por caracteres numricos. Utilizando a API JAX-RS esta validao pode ser realizada adicionando um padro de expresso regular que estas variveis devero possuir conforme demonstrado na seo 5.4. Ao receber uma requisio que no atenda a este padro, uma resposta com mensagem de status de nmero 404 (no encontrado). Caso ocorra uma exceo no momento do processamento da requisio a implementao da JAX-RS utilizada dever retornar uma mensagem de status 500 (Erro interno no servidor) conforme citado na seo 5.8. 6.3. Implementando a aplicao fornecedora Aps o levantamento das caractersticas dos recursos a serem projetados, chegada a hora de implement-los. A tabela abaixo demonstra a implementao do recurso pr-definido Fretes.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 @Path("/fretes") // Padro de @Consumes({"application/xml", @Produces({"application/xml", @Singleton // Definindo ciclo public class FretesRecurso { URI da Classe Recurso Raiz "application/json"}) // formatos aceitos "application/json"}) // formatos enviados de vida da Classe Recurso

@Context // Classe de contexto Jersey que recupera outras Classes Recurso protected ResourceContext resourceContext; @GET public List<Frete> consultarTodos( // Parametros de consulta (seo 1.1) @QueryParam("origem") Integer origem, @QueryParam("destino") Integer destino, @QueryParam("peso") Double peso, @QueryParam("data") Date data, @QueryParam("data") Date dataEnvioInicio, @QueryParam("data") Date dataEnvioFim) { return FreteDAO.consultar(

20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 }

origem, destino, peso, data, dataEnvioInicio, dataEnvioFim); } @POST public Response incluirFrete(Frete frete) { try{ FreteDAO.incluir(frete); resourceContext.getResource(FreteRecurso.class).alterar(frete); return Response.created(frete.getUri()).build(); } catch (Exception e){ throw new WebApplicationException(e); } } @Path("/{id : [0-9]+}") // Utilizao de Expresso regular public FreteRecurso getFreteRecurso() { // Mtodo alocador de sub-recurso return resourceContext.getResource(FreteRecurso.class); } @GET @Path("/cotacao") public Cotacao getCotacao( // Mtodo sub-recurso (seo 1.1) @QueryParam("origem") Integer origem, @QueryParam("destino") Integer destino, @QueryParam("peso") Double peso, @QueryParam("data") Date data) { return FreteDAO.cotacao(origem, destino, peso, data); }

Listagem 11 Recurso Raz FreteRecurso.

A tabela abaixo apresenta algumas observaes sobre a implementao da classe FretesRecursos e indica em qual seo deste artigo encontram-se mais detalhes: Linha Seo 01 02 03 04 07 10 13 34 35 41 5.1.2 5.5 5.5 5.1.3 5.7 5.2 5.2.1. 5.4. 5.3. 5.3. Descrio Caminho da Classe Recurso Raiz. Lista de formatos que podero ser enviados nas requisies. Lista de formatos que podero ser enviados nas respostas. Definio do ciclo de vida. Atributo utilizado para receber classe de contexto ResourceContext. Esta classe de contexto uma classe exclusiva da implementao Jersey e utilizada para recuperar instncias de outras Classes Recursos. Exemplo de um Mtodo Recurso, designado a responder a requisies de um mtodo HTTP especificado. Exemplo de parmetros do Mtodo Recurso que recebero os valores dos parmetros de consulta das requisies HTTP. Definindo padro de expresso regular para uma varivel de caminho. Exemplo de um Mtodo alocador de Sub-Recurso. O Mtodo Recurso getFreteRecurso contido na Classe Recurso FretesRecurso est alocando requisies com o padro /fretes/{id} para a Classe Recurso FreteRecurso. Exemplo de um Mtodo Sub-Recurso. O Mtodo Recurso getCotacao() representa um Sub-Recurso pois sua URI

Tabela 10 Comentrios sobre o cdigo da Classe Recurso FretesRecurso (listagem 11).

A listagem abaixo demostra o cdigo da Classe Recurso Frete, que representa os recursos que representam dados do tipo Frete:
01 @Singleton // Haver apenas uma instncia desta classe para a aplicao 02 public class FreteRecurso { 03 04 @Context 05 private UriInfo uri; 06 07 @GET 08 public Frete consultar(@PathParam("id") Integer id) { 09 return FreteDAO.consultarPorId(id); 10 } 11 12 @PUT 13 public Frete alterar(@PathParam("id") Integer id, Frete frete) { 14 frete.setUri(uri.getAbsolutePath()); 15 return FreteDAO.alterar(id, frete); 16 } 17 18 @DELETE 19 public void excluir(@PathParam("id") Integer id) { 20 FreteDAO.excluir(id); 21 } 22 }

Listagem 12 Sub-Recurso FreteRecurso, representa todos os recursos do tipo frete.

Concluso O objetivo deste artigo foi apresentar a tecnologia REST como uma ferramenta utilizada para promover a computao distribuda atravs da publicao de Servios disponibilizados na Web. Criada pelo principal autor do protocolo HTTP, este estilo arquitetural formado por um conjunto de regras que quando seguidas pelas aplicaes distribudas, fazem com que estas utilizem de forma mais apropriada a infra-estrutura da Web, melhorando os aspectos de acessibilidade, economia de recursos de rede, melhoria de performance e escalabilidade, conforme descrito na seo 3. Entretanto, para implementar uma aplicao no estilo REST, necessrio manipular mensagens HTTP, desta forma, desenvolvedores no habituados a utilizar este protocolo, podem encontrar dificuldades ao tentarem construir servios REST. Da mesma forma, estes desenvolvedores podem criar servios que no se adqem s restries definidas pelo REST, o que resultaria em servios que no se beneficiariam das vantagens oferecidas por este estilo arquitetural. Com o desenvolvimento da aplicao de exemplo, pode-se constatar que: Ao utilizar a API JAX-RS, o desenvolvimento de servios REST torna-se uma atividade simples e produtiva: Tarefas como a converso de dados realizada entre os objetos Java e as representaes enviadas ao cliente so automatizadas. Servios REST so disponibilizados atravs de Recursos. que devem ser corretamente projetados: Deve-se definir a hierarquia dos Recursos, quais mtodos cada recurso ir responder, quais representaes sero aceitas e fornecidas. Ao utilizar JAX-RS sem o conhecimento das caractersticas que um servio REST deve possuir, pode ocasionar em recursos mal projetados, por exemplo, um Mtodo-

Recurso que responda a requisies do tipo GET no pode excluir recursos. Bibliografia FIELDING, Roy T. Architectural Styles and the Design of Network-based Software Architectures. 2000. Tese (Doutorado) - UNIVERSITY OF CALIFORNIA, IRVINE 2000. Disponvel em: <http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm>. Acesso em 12 setembro 2009. RICHARDSON, Leonard; RUBY, Sam. RESTful Servios Web. 1. ed. Rio de Janeiro: Alta Books, 2007. 336 p. Fielding, et al. Hypertext Transfer Protocol HTTP/1.1. Junho 1999. Disponvel em: <http:// www.ietf.org/rfc/rfc2616.txt>. Acesso em 15 setembro 2009. HADLEY, Marc ; SANDOZ Paul.JAX-RS: Java API for RESTful Web Services. Sun Microsystems, Inc., Santa Clara CA USA, setembro 2008. Disponvel em: <https://jsr311.dev.java.net/drafts/spec20090917.pdf>. Acesso em 20 setembro 2009. SUN MICROSYSTEM INC.. The Java EE Tutorial.Santa Clara CA USA, 2009. Disponvel em: <http://dlc.sun.com/pdf/820-7627/820-7627.pdf>. Acesso em 7 setembro 2009. SILVA, Bruno L. P.; BUBACK, Silvano N. JSR 311 e Jersey: Web services no Java EE. Java Magazine, Graja RJ, v. 6 n. 60, p.72-82, ago.2008. PAUTASSO, Cesare; ZIMMERMANN, Olaf; LEYMANN, Frank. RESTful Web Services vs. Big Web Services: Making the Right Architectural Decision. 17th International World Wide Web Conference (WWW2008), Beijing China, p.805-814, abr. 2008. Disponvel em: <http://www2008.org/papers/pdf/p805-pautassoA.pdf> Acesso em: 7 Set. 2009.

Você também pode gostar