Criando uma API com Spring Data REST e auditando com Hibernate Envers

Silas Candiolli
CWI Software
Published in
5 min readMar 27, 2019

À medida que a linguagem de programação Java vai evoluindo a quantidade de código e configuração que escrevemos tende a diminuir juntamente. Antes havia muito XML para configurações do projeto, hoje em dia em projetos mais modernos isso é raro. Se você utiliza Spring é possível diminuir mais ainda porque muitas coisas já são transparentes para nós desenvolvedores, e por convenção ele se entende facilitando muito nossas vidas.

Agora pense na possibilidade de você definir suas entidade e repositórios baseado no seu modelo de dados, e magicamente seus métodos GET, POST, PUT, DELETE serem criados automaticamente. E poder auditar suas tabelas de forma simples, anotando suas entidades. Parece ótimo não é mesmo?!

Neste artigo pretendo apresentar essas duas bibliotecas para sabermos quando, como e porque utilizá-las no nosso dia-a-dia. Também espero que o projeto que utilizaremos nesse artigo possa servir como um ponto de partida para os que estão iniciando com Java ou Spring Boot, que ainda não conhecem bem a sua arquitetura mas que querem subir um serviço e ver as coisas funcionando.

Nesse projeto utilizaremos as seguintes bibliotecas:

Eu adicionei o link para a página de cada biblioteca, porém irei focar em explicar somente as duas principais deste artigo.

Hibernate Envers

O Envers é um módulo que faz parte do projeto Hibernate ORM (Mapeamento objeto relacional), e ele provê uma maneira fácil de fazer auditoria e versionamento de suas classes entidades.

Spring Data REST

O Spring Data REST faz parte do projeto guarda-chuva Spring Data, e facilita a criação de serviços da Web REST baseados em hipermídia sobre os repositórios Spring Data;

Ele se baseia nos repositórios do Spring Data, analisa o modelo de domínio de seu aplicativo e expõe recursos HTTP orientados por hipermídia para agregados contidos no modelo.

O projeto

Para trabalharmos com algo mais real, criei um projeto que visa organizar uma biblioteca musical, onde poderei criar músicas, álbuns e produtores musicais.

Para o nosso projeto de fato funcionar, ainda precisaremos de outras dependências que não veem ao caso explicar. Partindo do pressuposto que você já conhece o Maven, é possível baixar o projeto e ver o pom.xml completo aqui.

A estrutura do projeto ficará desta forma:

É possível ver que temos classes e arquivos de configuração criados. O que está dentro do pacote ‘br.com.candiolli.musiclibrary’ são classes Java. No pacote ‘resources’ são configurações, e na raiz do projeto o arquivo pom.xml é para as dependências do maven, ou seja, bibliotecas que vamos utilizar nesse projeto. Os outros arquivos podem ser ignorados no momento.

Hibernate Envers funcionando

Para exemplificar, falarei da entidade Music.java que representa uma tabela do banco de dados e que está anotada para ser auditada. Sabemos isso por causa da anotação @Audited e @AuditTable.

Dessa forma, três tabelas serão criadas no banco de dados: ‘music’, ‘music_audit’ e ‘revinfo’. A ‘revinfo’ é para versionar todas as alterações que as tabelas auditadas sofrem, e o que muda de fato fica registrado na tabela ‘music_audit’. Conforme imagem abaixo:

Isso pode se dar automaticamente ou previamente, dependendo da estratégia do hibernate. No meu caso, que está create-drop, será recriada toda vez que eu executar meu micro serviço.

Sabendo disso, podemos ver abaixo e entender as linhas das nossas tabelas. Temos uma música adicionada que depois sofreu uma alteração do seu nome, e isso tudo ficou logado. Lembrando que a tabela ‘revinfo’ versiona todas as tabelas ‘_audit’, por isso estamos vendo alguns rev que não estão na nossa tabela ‘music_audit’.

Spring Data REST funcionando

Como vimos anteriormente, a responsabilidade dessa biblioteca é descobrir nossas entidades e repositórios para expor nossos métodos de consumo REST.

Por exemplo, vamos ver a entidade Album.java e seu respectivo repositório:

As anotações que o Spring Data REST leva em consideração são @Entity e @Table. Assim ele sabe que essa classe é uma entidade que representa uma tabela do banco. Também é necessário ter um repositório criado para essa entidade, sem necessidade obrigatória de ser anotado.

Agora, vamos construir o projeto e depois executar. É preciso abrir o console na raiz do projeto:

$ mvn clean install
$ java -jar target/music-library-1.0-SNAPSHOT.jar

Você também pode executar com o próprio maven, dessa forma:

$ mvn spring-boot:run

E assim, você poderá acessar seu serviço com a url http://localhost:8080/api

Se tudo der certo, você deverá visualizar a resposta com os seus links disponíveis:

{
"_links" : {
"albums" : {
"href" : "http://localhost:8080/api/albums{?page,size,sort}",
"templated" : true
},
"productors" : {
"href" : "http://localhost:8080/api/album-productor{?page,size,sort}",
"templated" : true
},
"musics" : {
"href" : "http://localhost:8080/api/musics{?page,size,sort}",
"templated" : true
},
"profile" : {
"href" : "http://localhost:8080/api/profile"
}
}
}

Agora é possível entrar em cada ramificação, para criar, alterar, buscar ou excluir registros. Por exemplo, se você executar os request’s abaixo com cUrl, você irá adicionar um novo produtor e um novo album.

curl -X POST \
http://localhost:8080/api/album-productor \
-H 'Content-Type: application/json' \
-H 'Postman-Token: e180e099-ac14-4e7d-9042-d5ed1ac45f8f' \
-H 'cache-control: no-cache' \
-d '{
"name":"Gerge Martin"
}'
curl -X POST \
http://localhost:8080/api/albums \
-H 'Content-Type: application/json' \
-H 'Postman-Token: d1613266-86a1-46d9-9927-9c816414682a' \
-H 'cache-control: no-cache' \
-d '{
"title" :"Help!",
"author":"The Beatles",
"dateCreate":"01/01/1965 00:00:00",
"productor":{
"id":1
}
}'

Outro exemplo, para buscar todos álbuns que temos é só executar o seguinte:

curl -X GET \
http://localhost:8080/api/albums \
-H 'Content-Type: application/json' \
-H 'Postman-Token: 220818fe-1ea1-42ec-9c23-97c9cdfac0a9' \
-H 'cache-control: no-cache'

Gostaria de agradecer a você por fazer a leitura e espero ter ajudado a esclarecer o funcionamento dessas bibliotecas. Se puderem me mandem o feedback e dúvidas, eu agradeço muito.

Forte abraço, até a próxima.

--

--