Início > Programação > Introdução ao REST

Introdução ao REST

REST (REpresentational State Transfer) é um estilo de comunicação utilizado em web services. Hoje, REST é mais utilizado do que SOAP (Simple Object Access Protocol). Simplicidade e menor custo de transmissão de informações tornam o estilo REST ideal para uso na Internet. O estilo SOAP exige que se tenha um programa servidor para fornecer dados e um programa cliente para consumir dados além de implicar em maior consumo de banda para transmissão dos dados. Quando web services utilizam arquitetura REST eles passam a ser chamados de RESTful. REST oferece as seguintes vantagens quando comparado ao SOAP:

  • Web services RESTful são suportados por muitas ferramentas e por servidores de nuvem.
  • Serviços SOAP são mais difíceis de escalar. Por isso, REST é o estilo arquitetural escolhido para serviços expostos via Internet, como Twitter e Facebook.
  • A curva de aprendizado é baixa. Desenvolvedores são capazes de assimilar e utilizar REST em suas aplicações mais rápido do que SOAP.
  • REST utiliza um formato de mensagem menor do que o de SOAP. SOAP utiliza xml para todas as mensagens, o que aumenta o tamanho da mensagem e diminui a eficiência do serviço – menor custo de processamento e resposta mais rápida.

Dois conceitos importante do mundo dos web services são endpoints e recursos. O endpoint é uma URI (Uniform Resource Identifier) endereçada de forma padrão e que responde a requisições web. Recurso é um web service especializado que responde em uma determinada URI relativa ao endpoint que tem por propósito expor uma parte dos metadados do domínio do endpoint.

Ex:

URL: [https://www.site.com.br/endpoint/usuario/buscar/123]

Endpoint: [https://www.site.com.br/endpoint]

URI do Recurso: [/usuario/buscar/123]

Essa forma de mapear recursos é uma boa prática. Lê-se essa chamada como “recurso /usuario/buscar/, retorne o usuário que tem o identificador ‘123’”. É óbvio que “/usuario/buscar/” responde como GET, pois a chamada está sendo feita via parâmetro.

Embora o Jersey seja a implementação de referência para o JAX-RS, vamos fazer um exemplo utilizando o RESTEasy, que é a implementação do JBoss e ele vai nos fornecer as dependências em tempo de execução.

Exemplo

1. Adicione as dependências do RESTEsy para o seu projeto. Estou utilizando a versão 2.3.7.Final porque ela vem com o JBoss 6.4.

<dependency>
   <groupId>org.jboss.resteasy</groupId>
   <artifactId>resteasy-jaxrs</artifactId>
   <version>2.3.7.Final</version>
   <scope>provided</scope>
</dependency>
<dependency>
   <groupId>org.json</groupId>
   <artifactId>json</artifactId>
   <version>20131018</version>
</dependency>

2. No arquivo jboss-deployment-structure.xml do seu WEB-INF, informe ao JBoss que ele deve fornecer o RESTEasy para a sua aplicação em runtime. Você poderia empacotar sua versão do RESTEasy junto com sua aplicação, mas o JBoss ignora porque ele tem a dele.

<?xml version="1.0" encoding="UTF-8"?>
<jboss-deployment-structure xmlns="urn:jboss:deployment-structure:1.2" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<deployment>
   <dependencies>
      <module name="org.jboss.resteasy.resteasy-jaxrs"/>
   </dependencies>
</deployment>
</jboss-deployment-structure>

3. Vamos definir uma classe que representa os dados de um usuário que serão expostos pelo recurso.

@XmlRootElement
public class ResponseUsuario{
   private String nome;
   public String getNome(){
      return nome;
   }
   public void setNome(String nome){
      this.nome = nome;
   }
}

Essa classe é convertida para o JSON abaixo:

{
   "nome" : "José da Silva"
}

4. Vamos implementar o recurso “/usuario/buscar/{id}” relativo ao nosso endpoint. O método “buscar” recebe um “id” por parâmetro e retorna um JSON:

@Path("/usuario")
public class UsuarioResource {

   @EJB
   private UsuarioService service;

   @GET
   @Path("/buscar")
   @Produces(MediaType.APPLICATION_JSON)
   public Response buscar(@PathParam("id") String id) {
      try {
         Usuario usuario = service.buscar(id);
         ResponseUsuario respUsuario = new ResponseUsuario();
         respUsuario.setNome(usuario.getNome());
         return Response.status(Response.Status.OK).entity(respUsuario).
           header("Content-type", "application/json; charset=utf-8").
           build();
      } catch (ServicoException e) {
         return Response.status(Response.Status.FORBIDDEN).
           entity("Nao foi possivel localizar o usuario.").
           header("Content-type", "application/json; charset=utf-8").
           build();
      }
      return Response.status(Response.Status.FORBIDDEN).
         entity("Nao foi possivel localizar o usuario.").
         header("Content-type", "application/json; charset=utf-8").
         build();
      }
   }
}

5. Vamos definir um tratador de exceções padrão. Esse tratador intercepta, por exemplo, a tentativa de acesso a um recurso inexistente ou a uma chamada POST a um recurso que só suporta GET.

public class EndpointExceptionHandler 
   implements ExceptionMapper<Exception> {
   @Override
   public Response toResponse(Exception e) {
      return Response.serverError().entity(e.getMessage()).build();
   }
}

6. Por fim, vamos habilitar o servlet do RESTEasy e mapear as requisições para o “/”. Você poderia mapear o endpoint para qualquer outra localização supondo que o código do web service está acoplado ao código de outra aplicação, o que não é uma boa prática arquitetural.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://xmlns.jcp.org/xml/ns/javaee" 
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" 
id="WebApp_ID" version="3.1">
<display-name>EndPoint do Portal do Contador</display-name>
   <context-param>
      <param-name>resteasy.providers</param-name>
      <param-value>br.com.handler.EndpointExceptionHandler</param-value>
   </context-param>
   <context-param>
      <param-name>resteasy.scan</param-name>
      <param-value>true</param-value>
   </context-param>
   <context-param>
      <param-name>resteasy.servlet.mapping.prefix</param-name>
      <param-value>/</param-value>
   </context-param>
   <listener>
      <listener-class>
         org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
      </listener-class>
   </listener>
   <servlet>
      <servlet-name>resteasy-servlet</servlet-name>
      <servlet-class>
         org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
      </servlet-class>
   </servlet>
   <servlet-mapping>
      <servlet-name>resteasy-servlet</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>

Para testar, basta abrir o navegador e acessar a URL local:

teste

Referências

1. [http://resteasy.jboss.org/]
2. [https://jax-rs-spec.java.net]
3. [http://www.devmedia.com.br/resteasy-alem-da-especificacao/23309]
4. [https://www.ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm]
5. [http://www.devmedia.com.br/boas-praticas-com-web-services-restful/18020]
6. [https://www.w3.org/TR/wsdl20/#Endpoint]
7. [http://programmers.stackexchange.com/questions/138455/what-is-a-recommended-pattern-for-rest-endpoints-planning-for-foresighted-change]
8. [http://stackoverflow.com/questions/17662012/need-help-understanding-rest-api-endpoints]
9. [http://stackoverflow.com/questions/30580562/what-is-the-difference-between-resource-and-endpoint]
10. [http://www.eclipse.org/eclipselink/documentation/2.5/solutions/jpatoxml003.htm]
11. [http://stackoverflow.com/questions/24307106/how-to-annotate-a-list-using-xmlelement]
12. [http://stackoverflow.com/questions/12256221/automatic-xmlrootelement-wrapper-for-list]
13. [http://racksburg.com/choosing-an-http-status-code/]
14. [http://stackoverflow.com/questions/942951/rest-api-error-return-good-practices]
15. [http://searchsoa.techtarget.com/definition/REST]

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: