Spring boot com service discovery + especificação automática de API’s
Neste tutorial vou explicar como configurar uma solução Spring boot para que se registe num service registry, neste caso o Eureka e que garanta a geração da documentação das APIs com Swagger v2 de forma automática.
Eureka Server, como Service Registry
Para começar vamos criar um projecto que funcione como Service Registry, usando o Eureka Server, este serviço permitirá que todos os projectos clientes possam informar qual o seu endereço e porto, assim num cenário onde um serviço tenha que invocar outro pode fazê-lo usando apenas o seu application name.
Assim usando o spring initializer criamos a estrutura do projecto com as dependências necessárias, neste caso apenas com o “Eureka Server”
A dependência necessária é:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>
As seguintes configurações são simples:
Na classe onde está incluida a função main é necessário incluir a anotação @EnableEurekaServer
package com.example.eurekaserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServerApplication.class, args);
}
}
Depois no application.yml do projecto incluir as seguintes configurações:
server:
port: 8761
eureka:
client:
register-with-eureka: false
fetch-registry: false
Tipicamente o porto deafault para o Eureka server é o 8761, mas pode aqui ser alterado.
As configurações adicionais são para que o próprio Eureka Server não se tente registar nele próprio.
Fazendo run da solução ficamos com front-end HTML disponível quando acedemos ao endereço http://localhost:8761
Aplicação Cliente
Foquemo-nos agora nas aplicações cliente, para isso voltando ao Spring Initializer vamos criar a estrutura inicial com as seguintes dependencias.
Adicionalmente ainda necessitamos de uma dependencia extra para podermos gerar a especificação automática em OpenAPI usando Springfox, assim as dependências necessárias são:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
Neste cenário vamos criar uma aplicação muito simples que faz CRUD de um objecto Users e para isso expões dois endpoints:
- [POST] /users → permite a criação de um novo registo
- [GET] /users → permite listar todos os registos existentes
De seguida é necessário incluir as anotações necessárias que estarão sobretudo em dois níveis:
- Nos controllers onde serão identificados os nomes e descrições da API e dos serviços disponíveis;
- No modelo de dados das entidades, onde se podem especificar o tipo de dados, valores possíveis e se os campos são obrigatórios por exemplo.
Exemplo das anotações no controller
Exemplo das anotações no modelo da entidade:
Configuração do Springfox
O Springfox necessita apenas de um componente @Configuration onde ativamos o Swagger:
Configuração do Eureka Client
Para que a aplicação se possa registar no Eureka Server a única configuração necessária é feita no application.yml
server:
port: 9001
spring:
application:
name: Users
eureka:
client:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://localhost:8761/eureka
instance:
hostname: localhost
Onde a key spring.application corresponde ao application name no Eureka Server, as restantes configurações indicam que a aplicação se deve registar no servidor indicado na key eureka.client.service-url.defaultZone
Resultados
Levantando as duas soluções temos assim:
→ Eureka Server no endereço http://localhost:8761 com um interface HTML com os dados das aplicações registadas.
→ A aplicação cliente expõe dois interfaces:
- Swagger HTML http://localhost:9001/swagger-ui/
- Swagger JSON http://localhost:9001/v2/api-docs
Código da solução https://github.com/jppg/spring-eureka-swagger