Configurando uma Conexão SQL Server no JBoss com Microsoft JDBC Driver


Em um post anterior aprendemos como criar uma conexão via JBoss e um banco MSQL Server usando o JTDS Driver. Neste post falaremos do Microsoft JDBC Driver da Microsoft. Para configurar ele no JBoss seguiremos alguns passos bem simples:


1. Primeiro baixe o driver no site oficial da microsoft..


2. Extraia o arquivo recem baixado e localize o arquivo sqljdbc4.jar.


3. No seu JBOSS_HOME crie diretórios respeitando a seguinte hierarquia “modules\com\microsoft\main”. Dentro desse diretório coloque o arquivo recém baixado sqljdbc4.jar e crie um novo arquivo chamado module.xml com o seguinte conteúdo:


<module xmlns="urn:jboss:module:1.0" name="com.microsoft">
 <resources>
   <resource-root path="sqljdbc4.jar"/>
   </resources>
   <dependencies>
      <module name="javax.api"/>
      <module name="javax.transaction.api"/>
   </dependencies>
</module>


3. Agora precisamos modificar nosso standalone.xml adicionando as configurações abaixo à seção de datasources:


<datasource jndi-name="java:/SeuDatabase" pool-name="SeuDatabase">
   <connection-url>jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=SeuDatabase</connection-url>
   <driver>sqlserver</driver>
   <security>
      <user-name>seu_usuario</user-name>
      <password>sua_senha</password>
   </security>
</datasource>    


E na seção drivers:


<driver name="sqlserver" module="com.microsoft">
   <xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</xa-datasource-class>
</driver>


O resultado final deve ser similar a configuração abaixo:


<subsystem xmlns="urn:jboss:domain:datasources:1.2">
   <datasources>      
      <datasource jndi-name="java:/SeuDatabase" pool-name="SeuDatabase">
         <connection-url>jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=SeuDatabase</connection-url>
         <driver>sqlserver</driver>
         <security>
            <user-name>seu_usuario</user-name>
            <password>sua_senha</password>
         </security>
      </datasource>   
      
      <drivers>
         <driver name="sqlserver" module="com.microsoft">
            <xa-datasource-class>com.microsoft.sqlserver.jdbc.SQLServerXADataSource</xa-datasource-class>
         </driver>
      </drivers>
   </datasources>
</subsystem>


Agora aprendemos a criar uma conexão com uma base MSQL Server com os dois principais drivers com esse propósito. Mais uma vez para soluções mais complexas use o Google e sua criatividade. É isso aí bons estudos e se gostou da postagem torne-se um membro VIP e receba conteúdos exclusivos..


Tags: , , , , ,

Montando Um Ambiente De Desenvolvimento Java Completo

Esse é um post para aqueles que estão procurando começar a desenvolver em Java. Trata-se de um passo a passo em vídeos sobre como montar o ambiente de desenvolvimento Java completo. No primeiro vídeo eu faço uma pequena apresentação da série e dou algumas dicas rápidas.

No segundo vídeo aprendemos a baixar e instalar o Java 8 que pode ser baixado aqui.

No terceiro vídeo nos configuramos as variáveis de ambiente JAVA_HOME (C:\Program Files\Java\jdk1.8.0_92 – adapte esse endereço à sua realidade) e adicionamos sua referência ao Path (%JAVA_HOME%\bin).

No quarto vídeo realizamos a instalaçãp do Apache Maven que pode ser baixado aqui. E configuramos as variáveis de ambiente (C:\Program Files\Apache-Maven-3.3.9 – adapte esse endereço à sua realidade) e adicionamos sua referência ao Path (%M2_HOME%\bin).

Com o Maven já instalado nesse vídeo nós customizamos o diretório padrão em que salvamos as nossas dependências. Esse é um vídeo extra e se você tem espaço de sobra no seu HD pode simplesmente pular para o próximo vídeo.

No próximo vídeo eu demonstro como executar um projeto Maven se por acaso você já souber como fazer isso pode avançar direto para o próximo. Um ponto não mencionado no vídeo é que não raramente acontece é um proxy, firewall ou antivírus impedindo o download de nossas dependências então antes de xingar o Maven confira se essas três coisas não estão te sabotando.

Nesse vídeo nós aprendemos como instalar o Eclipse e como configurar o Maven nessa IDE. Você pode baixar o Eclipse aqui e a Spring Source Tool Suite aqui (a IDE que eu uso).

Agora veremos como importar e executar um projeto no Eclipse.

Os próximos vídeos é para aqueles que preferem trabalhar na IDE Netbeans que pode ser baixada aqui. Aprendemos qual opção de download escolher e como instalar.


No vídeo seguinte a gente importa e executa um projeto no Netbeans.

Nesse vídeo nos fazemos a instalação do GitBash que inclui o Git e um bash que você pode usar no lugar do prompt de comandos do DOS. As principais vantagens dele é prover funcionalidades similares às do Linux na linha de comando. O GitBash pode ser baixado aqui.


Agora nós instalaremos o MySQL que é um SGBD relativamente simples pra você iniciar seus estudos de Java acessando uma base de dados e pode ser baixado aqui.


Um passo óbvio depois de instalar um SGBD é instalar uma ferramenta de SGBD. No nosso caso instalaremos o HeidiSQL que usaremos para manipular os dados de nosso banco. Para baixá-lo clique aqui.


Nesse vídeo nos aprendemos como fazer um backup de uma base de dados.


E por fim aprendemos a restaurar um backup.

Com essas tecnologias configuradas temos bem além do básico necessário para trabalhar com Java. Como podem perceber você pode assistir os vídeos e instalar apenas as ferramentas que você precisar mas o objetivo final é te dar uma base tecnológica para construir aplicações Java se conectando a uma base de dados usando Maven. É isso aí bons estudos e se gostou da postagem torne-se um membro VIP e receba conteúdos exclusivos.

Configurando uma Conexão SQL Server no JBoss com JTDS


Existem dois drivers que podem ser utilizados para criar uma conexão via JBoss e um banco MSQL Server. Um é o Microsoft JDBC Driver da Microsoft e o outro é o JTDS. Muitos dizem que o último é superior ao oficial da Microsoft e neste post falaremos justamente dele. Para configurar ele no JBoss seguiremos alguns passos bem simples:


1. Primeiro baixe o driver no SourceForge.


2. No seu JBOSS_HOME crie diretórios respeitando a seguinte hierarquia “modules\net\sourceforge\jtds\main”. Dentro desse diretório coloque o jar recém baixado jtds-1.3.1.jar(versão atual) e crie um novo arquivo chamado module.xml com o seguinte conteúdo:


<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.0" name="net.sourceforge.jtds">
   <resources>
      <resource-root path="jtds-1.3.1.jar"/>
   </resources>
   <dependencies>
      <module name="javax.api"/>
      <module name="javax.transaction.api"/>
   </dependencies>
</module>


3. Agora precisamos modificar nosso standalone.xml adicionando as configurações abaixo à seção de datasources:


<datasource jndi-name="java:jboss/datasources/SeuDatabase" pool-name="SeuDatabase"
   enabled="true" use-java-context="true">
   <connection-url>jdbc:jtds:sqlserver://localhost:1433/SeuDatabase</connection-url>
   <driver>jtds</driver>
   <security>
      <user-name>seu_usuario</user-name>
      <password>sua_senha</password>
   </security>
</datasource>   


E na seção drivers:


<driver name="jtds" module="net.sourceforge.jtds">
   <driver-class>net.sourceforge.jtds.jdbc.Driver</driver-class>
</driver>


O resultado final deve ser similar a configuração abaixo:


<subsystem xmlns="urn:jboss:domain:datasources:1.2">
   <datasources>   
   
      <datasource jndi-name="java:jboss/datasources/SeuDatabase" pool-name="SeuDatabase"
         enabled="true" use-java-context="true">
         <connection-url>jdbc:jtds:sqlserver://localhost:1433/SeuDatabase</connection-url>
         <driver>jtds</driver>
         <security>
            <user-name>seu_usuario</user-name>
            <password>sua_senha</password>
         </security>
      </datasource>   
      
      <drivers>
         <driver name="jtds" module="net.sourceforge.jtds">
            <driver-class>net.sourceforge.jtds.jdbc.Driver</driver-class>
         </driver>
      </drivers>
   </datasources>
</subsystem>


Essa é a configuração mais básica de todas e acredito que será o suficiente para você começar a se conectar com uma base MSQL Server para soluções mais complexas use o Google e sua criatividade. No próximo post explicaremos como fazer a mesma coisa só que dessa vez usando o Microsoft JDBC Driver da Microsoft.É isso aí bons estudos e se gostou da postagem torne-se um membro VIP e receba conteúdos exclusivos.


Tags: , , , , ,

Criando um novo projeto a partir de um Archetype Maven

Em uma postagem anterior você viu como criar um Archetype Maven a partir de um projeto existente agora chegou o momento de criarmos um projeto novo a partir do nosso archetype. Primeiro você precisa clonar esse projeto no seu computador. Para isso abra o terminal no diretório em que deseja armazenar o código e execute o comando abaixo.

git clone https://github.com/leandrocgsi/erudio-rest-api-archetype.git

Abra a pasta gerada ela deverá se parecer com a imagem abaixo.

OpenFolder

Abra o terminal nessa pasta e execute o seguinte comando.

mvn clean install

Ele deve se parecer com a imagem abaixo

CleanInstall

Agora vá até o diretorio em que deseja criar o seu projeto e execute o seguinte comando (formatado para facilitar a leitura execute tudo na mesma linha).

mvn archetype:generate -DarchetypeGroupId=br.com.semeru
    -DarchetypeArtifactId=jsf-hibernate-spring-security-archetype
    -DarchetypeVersion=0.1.0
    -DgroupId=br.com.your.domain
    -DartifactId=your-project-name
    -Dversion=1.0-SNAPSHOT
    -Dpackage=br.com.your.domain

Onde você deve ajustar os parâmetros DgroupId para seu group ID, DartifactId para o nome do seu projeto, Dversion para o numero de versão desejado, Dpackage para sua base de pacotes.

Ele deve se parecer com a imagem abaixo.

GenerateProject

O Maven irá lhe perguntar se você deseja alterar a versão do seu projeto e a estrutura de pacotes como está destacado na imagem abaixo. Se você não quiser alterar nada apenas digite Enter Enter. Se tudo tiver corrido bem você deverá ver uma imagem similar à que se segue e isso significa que o seu projeto foi criado com sucesso 😉

Building1

Agora só precisamos importar nosso projeto na nossa IDE favorita (STS – Spring Suource Tool Suite, baseada no Eclipse, no meu caso). Acesse o menu File >> Import >> Maven >> Existing Maven Projects >> Next.

Importing1

Como na imagem abaixo digite ou navegue até o diretório onde se encontra o seu código e clique em Browse >> Finish.

Importing2

Agora que tudo está pronto basta codar a nossa aplicação. Caso não saiba como executar o projeto clique aqui e siga o passo a passo.

Tags: , ,

Aplicações RESTful HATEOAS com SpringBoot


O HATEOAS, é uma das principais constraints arquiteturais do REST e possibilita a navegação entre recursos, que são representações dos modelos de negócio da aplicação. Esse post é bem mão na massa e se quiser aprofundar um pouco mais em conceitos teóricos de HATEOAS confira o nosso post Entendendo HATEOAS. Vamos tomar como base a aplicação desenvolvida no nosso outro post Documentando aplicações REST com SpringBoot e Swagger. Para começar você pode baixar o código deste post aqui e descompactar o arquivo zip e importar na sua IDE preferida ou clonar usando Git:


git clone https://github.com/leandrocgsi/simple-rest-example-swagger.git


Primeiro altere o pom.xml adicionando os trechos destacados por comentários abaixo.


<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>br.com.erudio</groupId>
    <artifactId>simple-rest-example-hateoas</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.3.3.RELEASE</version>
    </parent>
    
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        
        <!-- Adicione a dependencia de HATEOAS-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-hateoas</artifactId>
        </dependency>
        
        <dependency>
            <groupId>com.mangofactory</groupId>
            <artifactId>swagger-springmvc</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.ajar</groupId>
            <artifactId>swagger-spring-mvc-ui</artifactId>
            <version>0.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tomcat.embed</groupId>
            <artifactId>tomcat-embed-jasper</artifactId>
            <scope>provided</scope>
        </dependency>
        
        <!-- Adicione as dependencias de teste -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <scope>test</scope>
        </dependency>        
        
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
    
    <repositories>
        <repository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </repository>
        <repository>
            <id>jcenter-release</id>
            <name>jcenter</name>
            <url>http://oss.jfrog.org/artifactory/oss-release-local/</url>
        </repository>
    </repositories>
    
    <pluginRepositories>
        <pluginRepository>
            <id>spring-releases</id>
            <url>https://repo.spring.io/libs-release</url>
        </pluginRepository>
    </pluginRepositories>
    
</project>


Primeiro vamos alterar a classe Greeting que agora ira extender ResourceSupport.


package br.com.erudio.models;

import org.springframework.hateoas.ResourceSupport;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Greeting extends ResourceSupport {

    private final long idGreeting;
    private final String content;

    @JsonCreator
    public Greeting(@JsonProperty("id") long id, @JsonProperty("content") String content) {
        this.idGreeting = id;
        this.content = content;
    }

    public long getIdGreeting() {
        return idGreeting;
    }

    public String getContent() {
        return content;
    }
}


Agora adicione os trechos comentados a classe GreetingController.


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.concurrent.atomic.AtomicLong;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Greeting;

@Api(value = "greeting")
@RestController
@RequestMapping("/greeting")
public class GreetingController {

    private static final String template = "Hello, %s!";
    private final AtomicLong counter = new AtomicLong();

	@ApiOperation(value = "Show Greeting Message" )
	@ResponseStatus(HttpStatus.OK)
    @RequestMapping(method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public HttpEntity<Greeting> greeting(@RequestParam(value="name", defaultValue="World") String name) {
		Greeting greeting = new Greeting(counter.incrementAndGet(), String.format(template, name));
		
		// Na prática essa linha adiciona uma auto referência ao próprio endpoint
		// e apenas esse pequeno trecho de código já é o suficiente para que o endpoint 
		// greeting seja HATEOAS
		greeting.add(linkTo(methodOn(GreetingController.class).greeting(name)).withSelfRel());
        
		return new ResponseEntity<Greeting>(greeting, HttpStatus.OK);
    }
}


Se você iniciar a aplicação e acessar o endereço localhost:8080/greeting verá algo similar a imagem abaixo.

postagem_4_0


package br.com.erudio.models;

import java.io.Serializable;

import org.springframework.hateoas.ResourceSupport;

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

// Adicione a anotação @JsonIgnoreProperties
@JsonIgnoreProperties(ignoreUnknown = true)

//Extenda ResourceSupport
public class Person extends ResourceSupport implements Serializable{
    
    private static final long serialVersionUID = 1L;
    
	// Por padrão implementação HATEOAS do Spring tem um atributo id
	// como default por isso o ID de nossa entidade deve ser alterado
    private Long idPerson;
    private String firstName;
    private String lastName;
    private String address;
    
    public Person() {}

	public Long getIdPerson() {
        return idPerson;
    }
    
    public void setIdPerson(Long id) {
        this.idPerson = id;
    }
    
    public String getFirstName() {
        return firstName;
    }
    
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    
    public String getLastName() {
        return lastName;
    }
    
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    
    public String getAddress() {
        return address;
    }
    
    public void setAddress(String address) {
        this.address = address;
    }
}


Agora vamos alterar a classe PersonController:


package br.com.erudio.web.controllers;
 
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;
 
import java.util.ArrayList;
import java.util.List;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
 
import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;
 
import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;
 
@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
     
    @Autowired
    private PersonService personService;
	@ApiOperation(value = "Find person by ID" )
    @ResponseStatus(HttpStatus.OK)
    @RequestMapping(value = "/{personId}", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    public Person get(@PathVariable(value = "personId") String personId){
        Person person = personService.findById(personId);
		
		//Adicione uma auto referencia ao método get do controller passando o ID como parâmetro
        person.add(linkTo(methodOn(PersonController.class).get(personId)).withSelfRel());
		return person;
    }
     
    .
    .
    .
     
}


Note que ao acessar esse recurso com uma ferramenta como o POSTman teremos uma resultado similar a imagem abaixo.


postagem_4_1


Agora vamos alterar o findAll:


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;

@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
	
	@Autowired
	private PersonService personService;
	
	.
	.
	.
	
	@ApiOperation(value = "Find all persons" )
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(value = "/findAll", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
	public List<Person> findAll(){
		List<Person> persons = personService.findAll();
		ArrayList<Person> personsReturn = new ArrayList<Person>();
		for (Person person : persons) {
			String idPerson = person.getIdPerson().toString();
			
			// Adicione uma referencia ao método get do controller passando o ID como parâmetro
			// isso é feito para todos os elementos da lista
			person.add(linkTo(methodOn(PersonController.class).get(idPerson)).withSelfRel());
			personsReturn.add(person);
		}
		return personsReturn;
	}
	
	.
	.
	.
	
}


A imagem abaixo nos mostra o resultado dessa mudança. A nossa lista nos tras referencias únicas para cada um dos recursos.


postagem_4_2


Agora vamos adicionar o suporte a HATEOAS ao verbo POST da nossa aplicação.


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;

@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
	
	@Autowired
	private PersonService personService;
	
	.
	.
	.
	
	@ApiOperation(value = "Create a new person" )
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
	public Person create(@RequestBody Person person){
		Person createdPerson = personService.create(person);
		String idPerson = createdPerson.getIdPerson().toString();
		
		// Após criarmos um novo recurso do tipo Person nós recuperamos seu ID e adicionamos
		// uma referencia ao método get do controller passando o ID como parâmetro		
		createdPerson.add(linkTo(methodOn(PersonController.class).get(idPerson)).withSelfRel());
		return createdPerson;
	}
	
	.
	.
	.
	
}


Como se pode ver na imagem após salvar uma nova pessoa a aplicação retorna um link para que as informações da mesma possam ser acessadas.


postagem_4_3


Agora vamos modificar o verbo PUT.


package br.com.erudio.web.controllers;

import static org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo;
import static org.springframework.hateoas.mvc.ControllerLinkBuilder.methodOn;

import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import com.wordnik.swagger.annotations.Api;
import com.wordnik.swagger.annotations.ApiOperation;

import br.com.erudio.models.Person;
import br.com.erudio.services.PersonService;

@Api(value = "person")
@RestController
@RequestMapping("/person/")
public class PersonController {
	
	@Autowired
	private PersonService personService;
		
	.
	.
	.
	
	@ApiOperation(value = "Update an existing person")
	@ResponseStatus(HttpStatus.OK)
	@RequestMapping(method = RequestMethod.PUT,consumes = MediaType.APPLICATION_JSON_VALUE)
	public Person update(@RequestBody Person person){
		Person updatedPerson = personService.update(person);
		String idPerson = updatedPerson.getIdPerson().toString();
		
		// Após atualizarmos um recurso nós recuperamos seu ID e adicionamos
		// uma referencia ao método get do controller passando o ID como parâmetro		
		updatedPerson.add(linkTo(methodOn(PersonController.class).get(idPerson)).withSelfRel());		
		return updatedPerson;
	}
	
	.
	.
	.
	
}


Da mesma forma que com o verbo POST após atualizar uma pessoa a aplicação retorna um link para que as informações da mesma possam ser acessadas.


postagem_4_4


Como o verbo DELETE exclui um recurso não há necessidade de adicionar suporte a HATEOAS nele. Sendo assim fechamos a nossa implementação e podemos dizer que a nossa API é finalmente RESTful. Assim como nos posts anteriores você pode baixar o código deste post aqui e descompactar o arquivo zip e importar na sua IDE preferida ou clonar usando Git:

git clone https://github.com/leandrocgsi/simple-rest-example-hateoas.git


É isso aí bons estudos e continuem ligados no blog para mais novidades 😉


Tags: , , , , ,

Entendendo HATEOAS


HATEOAS (Hypermedia as the Engine of Application State) é uma constraint arquitetural de aplicações REST. Uma API HATEOAS provê informações que permite navegar entre seus endpoints de forma dinâmica visto que inclui links junto às respostas. Esta capacidade a difere de sistemas baseados em SOA e interfaces dirigidas por WSDL(pronuncia-se uísdou). Com SOA, servidores e clientes usualmente devem acessar uma especificação fixa que pode ser acessada em outro lugar na API, ou em um website, ou as vezes distribuído por email.


Nota: Pronunciar HATEOAS não é fácil e pode variar bastante. Algumas pessoas pronunciam algo como “riteos“, outros como “reitos” ou como “reidôs“. Alguns podem se referir a esse conceito arquitetural por hypermedia-driven system – algo como sistema dirigido por hipermídia.


Exemplos


O código a seguir representa um objeto Cliente.


class Cliente {
    String nome;
}


Uma representação JSON tradicional seria algo como:


{ 
    "nome" : "Leandro"
}


Os dados do Cliente estam lá, mas os dados não contém nada de relevante sobre suas conexões. Uma representação baseada em HATEOAS deve ser similar ao JSON abaixo:


{
    "nome": "Leandro",
    "links": [ {
        "rel": "self",
        "href": "http://localhost:8080/Cliente/1"
    } ]
}


A resposta não contém somente o nome de uma pessoa, mas inclui uma URL com o endereço de onde as informações dessa pessoa podem ser localizadas.
rel significa relacionamento. No nosso caso o link autoreferencia a pessoa. Sistemas mais complexos incluem outros tipos de relacionamentos. Por exemplo, uma ordem de compra pode ter um relacionamento com cliente”rel”:”Cliente” vinculando a ordem ao Cliente.
href é uma URL completa que define um único recurso.


Nota: Apesar de meus exemplos serem em JSON, XML também é aceito como um formato de resposta padrão. HATEOAS não impõe a exigência à um formato em específico. O seu foco é prover links que possibilite navegar entre os recursos de uma API.


Apesar de nossos exemplos serem bem simples é possível construir relações mais complexas. O HATEOAS, facilita aos desenvolvedores, de aplicações cliente, acessar os recursos de uma API sem precisar definir uma especificação, criar um documento externo ou uma wiki para isso.
Observe o JSON abaixo:


{
    "conteudo": [ {
        "preco": 499.00,
        "descricao": "HD Seagate 2TB",
        "nome": "HD S2TB",
        "links": [ {
            "rel": "self",
            "href": "http://localhost:8080/produto/1"
        } ],
        "atributos": {
            "conector": "SATA"
        }
    }, {
        "preco": 49.00,
        "descricao": "Mouse Óptico Dell",
        "nome": " Mouse",
        "links": [ {
            "rel": "self",
            "href": "http://localhost:8080/produto/3"
        } ],
        "atributos": {
            "conector": "wireless"
        }
    } ],
    "links": [ {
        "rel": "produto.consulta",
        "href": "http://localhost:8080/produto/consulta"
    } ]
}

Não apenas os itens e seus precos mostrados, mas também uma URL para cada recurso, fornecendo informações claras sobre como acessar cada recurso. De acordo com o modelo de maturidade de Richardson, HATEOAS é considerado o ultimo nível do REST. Isto significa que em uma aplicação HATEOAS presume-se que os verbos padrão de uma aplicação REST como GET, POST, PUT e DELETE também são adotados. Sendo que cada um deles, como é mostrado acima, provê ao cliente os links necessários ao acesso à uma informação.


É isso aí continuem ligados no blog e em breve teremos uma postagem bem mão na massa com HATEOAS e o nosso velho conhecido Spring Boot. Bons estudos 😉

Tags: , , ,