Microsserviços com Spring Boot. Parte 3. Criando um microsserviço de conversão de moeda

Esta é a terceira parte de uma série de artigos sobre os conceitos básicos de arquiteturas de microsserviço, nos quais você aprenderá como criar um microsserviço para conversão de moeda.

Nesta série de artigos, você se familiarizará com o conceito de microsserviços e aprenderá a criar microsserviços usando o Spring Boot e o Spring Cloud.

Este guia o ajudará a aprender o básico de arquiteturas de microsserviço. Também começaremos a analisar a implementação básica de microsserviços com o Spring Boot.

Criaremos um par de microsserviços e os faremos se comunicar usando os servidores de nome Eureka (Eureka Naming Server) e Ribbon para equilibrar a carga no lado do cliente.

Este artigo é parte da série Spring Boot Microservices:


Você vai aprender


  • Como criar um microsserviço usando o Spring Boot.
  • Como usar o RestTemplate para criar um serviço REST.
  • Como usar o Feign para criar um serviço REST.
  • Benefícios do Feign sobre o RestTemplate.

Visão geral dos recursos


O Serviço de Conversão de Moeda (CCS) pode converter muitas moedas em outra moeda. Ele usa o serviço Forex para obter os valores atuais de troca de moeda. O CCS é um consumidor de serviços.

Um exemplo de solicitação e resposta é mostrado abaixo:

GET to http://localhost:8100/currency-converter/from/EUR/to/INR/quantity/10000 

 { id: 10002, from: "EUR", to: "INR", conversionMultiple: 75, quantity: 10000, totalCalculatedAmount: 750000, port: 8000, } 

A solicitação acima permite determinar o valor de 10.000 euros em rúpias indianas.
TotalCalculatedAmount é 750.000 INR. O diagrama abaixo mostra o relacionamento entre o CCS e o FS.



Estrutura do código do projeto


A captura de tela a seguir mostra a estrutura do projeto que criaremos.



Alguns elementos do projeto:

  • SpringBootMicroserviceCurrencyConversionApplication.java é a classe do aplicativo Spring Boot criada usando o Spring Initializer. Essa classe atua como o ponto de inicialização do aplicativo.
  • pom.xml - contém todas as dependências necessárias para criar este projeto. Usaremos a Web do Spring Boot Starter.
  • CurrencyConversionBean.java - O bean para armazenar a resposta que queremos enviar.
  • CurrencyExchangeServiceProxy.java - esse será o Feign Proxy para chamar o serviço Forex.
  • CurrencyConversionController.java - Controlador Spring REST que fornece um serviço de conversão de moeda. Ele usará CurrencyExchangeServiceProxy para chamar o serviço Forex.

Ferramentas que você precisa


  • Maven 3.0+ - ferramenta de criação
  • Seu IDE favorito. Nós usamos o Eclipse.
  • JDK 1.8+

Projeto Maven pronto com amostras de código


O repositório do Github tem todos os exemplos de código.

Criando um projeto usando o Spring Initializr


Criar um microsserviço com o Spring Initializr é fácil.

O Spring Initializr é uma ótima ferramenta para criar rapidamente seus projetos do Spring Boot.

Com a ajuda do Spring Initializr, você pode criar uma variedade de projetos.



As etapas a seguir devem ser seguidas para criar um projeto de desenvolvimento de serviços da web:

1. Inicie o Spring Initializr e digite o seguinte:

  • Digite com.in28minutes.springboot.microservice.example.currencyconversion como um grupo.
  • Digite spring-boot-microservice-currency-conversion como um artefato.
  • Selecione as seguintes dependências: Web , DevTools , Feign

2. Clique em Gerar projeto .

3. Importe o projeto no Eclipse: Arquivo -> Importar -> Projeto Maven existente.

Lembre - se de listar Feign nas dependências.

Criando CurrencyConversionBean


Este é um bean simples para criar uma resposta.

 public class CurrencyConversionBean { private Long id; private String from; private String to; private BigDecimal conversionMultiple; private BigDecimal quantity; private BigDecimal totalCalculatedAmount; private int port; public CurrencyConversionBean() { } public CurrencyConversionBean(Long id, String from, String to, BigDecimal conversionMultiple, BigDecimal quantity, BigDecimal totalCalculatedAmount, int port) { super(); this.id = id; this.from = from; this.to = to; this.conversionMultiple = conversionMultiple; this.quantity = quantity; this.totalCalculatedAmount = totalCalculatedAmount; this.port = port; } 

Implementando um cliente REST com RestTemplate


O código abaixo demonstra a implementação de um cliente REST para chamar um serviço Forex e processar uma resposta. Como você pode ver, para fazer uma simples chamada de serviço, você precisa escrever muito código.

 @RestController public class CurrencyConversionController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}") public CurrencyConversionBean convertCurrency(@PathVariable String from, @PathVariable String to, @PathVariable BigDecimal quantity) { Map<String, String> uriVariables = new HashMap<>(); uriVariables.put("from", from); uriVariables.put("to", to); ResponseEntity<CurrencyConversionBean> responseEntity = new RestTemplate().getForEntity( "http://localhost:8000/currency-exchange/from/{from}/to/{to}", CurrencyConversionBean.class, uriVariables); CurrencyConversionBean response = responseEntity.getBody(); return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity, quantity.multiply(response.getConversionMultiple()), response.getPort()); } 

Configurar nome e porta do aplicativo


/spring-boot-microservice-currency-conversion-service/src/main/resources/application.properties

 spring.application.name=currency-conversion-service server.port=8100 

Teste de microsserviço


Inicie o aplicativo Spring Boot executando SpringBootMicroserviceCurrencyConversionApplication.java

 GET to http://localhost:8100/currency-converter/from/EUR/to/INR/quantity/10000 

 { id: 10002, from: "EUR", to: "INR", conversionMultiple: 75, quantity: 10000, totalCalculatedAmount: 750000, port: 8000, } 

Criando Proxies Feign


O Feign fornece a melhor alternativa ao RestTemplate para chamar a API REST.

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyExchangeServiceProxy.java

 package com.in28minutes.springboot.microservice.example.currencyconversion; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name="forex-service" url="localhost:8000") public interface CurrencyExchangeServiceProxy { @GetMapping("/currency-exchange/from/{from}/to/{to}") public CurrencyConversionBean retrieveExchangeValue (@PathVariable("from") String from, @PathVariable("to") String to); } 

Primeiro, definimos um proxy simples:

  • @FeignClient (name = "forex-service" url = "localhost: 8100") - declara que este é um cliente Feign e a URL onde o serviço Forex está localizado é localhost: 8100
  • @GetMapping ("/ casa de câmbio / de / {from} / para / {to}") - o URI do serviço que gostaríamos de usar

Usando Feign Proxies em um Controlador de Microsserviços


Fazer uma chamada através de um proxy é muito simples. Você verá isso em ação no código abaixo. Tudo o que precisávamos fazer era conectar automaticamente o proxy e usá-lo para chamar o método.

 @Autowired private CurrencyExchangeServiceProxy proxy; @GetMapping("/currency-converter-feign/from/{from}/to/{to}/quantity/{quantity}") public CurrencyConversionBean convertCurrencyFeign(@PathVariable String from, @PathVariable String to, @PathVariable BigDecimal quantity) { CurrencyConversionBean response = proxy.retrieveExchangeValue(from, to); logger.info("{}", response); return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity, quantity.multiply(response.getConversionMultiple()), response.getPort()); } 

Habilitando Feign Clients


Antes de podermos usar o Feign, precisamos habilitá-lo usando a anotação @EnableFeignClients no pacote apropriado em que os proxies do cliente são definidos.

 @SpringBootApplication @EnableFeignClients("com.in28minutes.springboot.microservice.example.currencyconversion") @EnableDiscoveryClient public class SpringBootMicroserviceCurrencyConversionApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMicroserviceCurrencyConversionApplication.class, args); } } 

Testando um microsserviço usando o Feign


 GET to http://localhost:8100/currency-converter-feign/from/EUR/to/INR/quantity/10000 


 { id: 10002, from: "EUR", to: "INR", conversionMultiple: 75, quantity: 10000, totalCalculatedAmount: 750000, port: 8000, } 

Sumário


Criamos dois microsserviços e estabelecemos uma conexão entre eles.



No entanto, codificamos o URL do FS para o CCS. Isso significa que, quando novas instâncias do FS são iniciadas, não temos como distribuir a carga entre elas. Na próxima parte, habilitaremos o balanceamento de carga no lado do cliente usando o Ribbon.

Código de exemplo completo

/spring-boot-microservice-currency-conversion-service/pom.xml


 <?xml version="1.0" encoding="UTF-8"?> <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>com.in28minutes.springboot.microservice.example.currency-conversion</groupId> <artifactId>spring-boot-microservice-currency-conversion</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>spring-boot-microservice-currency-conversion</name> <description>Microservices with Spring Boot and Spring Cloud - Currency Conversion Service</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.M3</version> <relativePath /> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> <spring-cloud.version>Finchley.M2</spring-cloud.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-feign</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring-cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project> 

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyConversionBean.java


 package com.in28minutes.springboot.microservice.example.currencyconversion; import java.math.BigDecimal; public class CurrencyConversionBean { private Long id; private String from; private String to; private BigDecimal conversionMultiple; private BigDecimal quantity; private BigDecimal totalCalculatedAmount; private int port; public CurrencyConversionBean() { } public CurrencyConversionBean(Long id, String from, String to, BigDecimal conversionMultiple, BigDecimal quantity, BigDecimal totalCalculatedAmount, int port) { super(); this.id = id; this.from = from; this.to = to; this.conversionMultiple = conversionMultiple; this.quantity = quantity; this.totalCalculatedAmount = totalCalculatedAmount; this.port = port; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getFrom() { return from; } public void setFrom(String from) { this.from = from; } public String getTo() { return to; } public void setTo(String to) { this.to = to; } public BigDecimal getConversionMultiple() { return conversionMultiple; } public void setConversionMultiple(BigDecimal conversionMultiple) { this.conversionMultiple = conversionMultiple; } public BigDecimal getQuantity() { return quantity; } public void setQuantity(BigDecimal quantity) { this.quantity = quantity; } public BigDecimal getTotalCalculatedAmount() { return totalCalculatedAmount; } public void setTotalCalculatedAmount(BigDecimal totalCalculatedAmount) { this.totalCalculatedAmount = totalCalculatedAmount; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } } 

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyConversionController.java


 package com.in28minutes.springboot.microservice.example.currencyconversion; import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; @RestController public class CurrencyConversionController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired private CurrencyExchangeServiceProxy proxy; @GetMapping("/currency-converter/from/{from}/to/{to}/quantity/{quantity}") public CurrencyConversionBean convertCurrency(@PathVariable String from, @PathVariable String to, @PathVariable BigDecimal quantity) { Map<String, String> uriVariables = new HashMap<>(); uriVariables.put("from", from); uriVariables.put("to", to); ResponseEntity<CurrencyConversionBean> responseEntity = new RestTemplate().getForEntity( "http://localhost:8000/currency-exchange/from/{from}/to/{to}", CurrencyConversionBean.class, uriVariables); CurrencyConversionBean response = responseEntity.getBody(); return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity, quantity.multiply(response.getConversionMultiple()), response.getPort()); } @GetMapping("/currency-converter-feign/from/{from}/to/{to}/quantity/{quantity}") public CurrencyConversionBean convertCurrencyFeign(@PathVariable String from, @PathVariable String to, @PathVariable BigDecimal quantity) { CurrencyConversionBean response = proxy.retrieveExchangeValue(from, to); logger.info("{}", response); return new CurrencyConversionBean(response.getId(), from, to, response.getConversionMultiple(), quantity, quantity.multiply(response.getConversionMultiple()), response.getPort()); } } 

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/CurrencyExchangeServiceProxy.java


 package com.in28minutes.springboot.microservice.example.currencyconversion; import org.springframework.cloud.netflix.feign.FeignClient; import org.springframework.cloud.netflix.ribbon.RibbonClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name="forex-service" url="localhost:8000") public interface CurrencyExchangeServiceProxy { @GetMapping("/currency-exchange/from/{from}/to/{to}") public CurrencyConversionBean retrieveExchangeValue (@PathVariable("from") String from, @PathVariable("to") String to); } 

/spring-boot-microservice-currency-conversion-service/src/main/java/com/in28minutes/springboot/microservice/example/currencyconversion/SpringBootMicroserviceCurrencyConversionApplication.java


 package com.in28minutes.springboot.microservice.example.currencyconversion; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.netflix.feign.EnableFeignClients; @SpringBootApplication @EnableFeignClients("com.in28minutes.springboot.microservice.example.currencyconversion") public class SpringBootMicroserviceCurrencyConversionApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMicroserviceCurrencyConversionApplication.class, args); } } 

/spring-boot-microservice-currency-conversion-service/src/main/resources/application.properties


 spring.application.name=currency-conversion-service server.port=8100 

/spring-boot-microservice-currency-conversion-service/src/test/java/com/in28minutes/springboot/microservice/example/currencyconversion/SpringBootMicroserviceCurrencyConversionApplicationTests.java


 package com.in28minutes.springboot.microservice.example.currencyconversion; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class SpringBootMicroserviceCurrencyConversionApplicationTests { @Test public void contextLoads() { } } 

Source: https://habr.com/ru/post/pt485094/


All Articles