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:

https://gist.github.com/jppg/f671e429714ced4217a19130dc2614fc

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.

http://localhost:8761

→ A aplicação cliente expõe dois interfaces:

Código da solução https://github.com/jppg/spring-eureka-swagger

I’m passionate about life, nature & technology. I love learning and help other people to evolve. I have a dream of teaching my children to program early.

I’m passionate about life, nature & technology. I love learning and help other people to evolve. I have a dream of teaching my children to program early.