Microservices avec Spring Boot. Partie 3. Création d'un microservice de conversion de devises

Il s'agit de la troisième partie d'une série d'articles sur les bases des architectures de microservices, dans laquelle vous apprendrez à créer un microservice pour la conversion de devises.

Dans cette série d'articles, vous vous familiariserez avec le concept des microservices et apprendrez à créer des microservices à l'aide de Spring Boot et Spring Cloud.

Ce guide vous aidera à apprendre les bases des architectures de microservices. Nous allons également commencer à examiner l'implémentation de base des microservices avec Spring Boot.

Nous allons créer une paire de microservices et les faire communiquer entre eux à l'aide des serveurs de noms Eureka (Eureka Naming Server) et Ribbon pour équilibrer la charge côté client.

Cet article fait partie de la série Spring Boot Microservices:


Vous apprendrez


  • Comment créer un microservice à l'aide de Spring Boot.
  • Comment utiliser RestTemplate pour créer un service REST.
  • Comment utiliser Feign pour créer un service REST.
  • Avantages de Feign sur RestTemplate.

Présentation des ressources


Le service de conversion de devises (CCS) peut convertir de nombreuses devises dans une autre devise. Il utilise le service Forex pour obtenir les valeurs de change actuelles. CCS est un consommateur de services.

Un exemple de demande et de réponse est présenté ci-dessous:

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, } 

La demande ci-dessus vous permet de déterminer la valeur de 10 000 euros en roupies indiennes.
Le montant total calculé est de 750 000 INR. Le diagramme ci-dessous montre la relation entre CCS et FS.



Structure du code de projet


La capture d'écran suivante montre la structure du projet que nous allons créer.



Quelques éléments du projet:

  • SpringBootMicroserviceCurrencyConversionApplication.java est la classe d'application Spring Boot créée à l'aide de Spring Initializer. Cette classe sert de point de lancement d'application.
  • pom.xml - contient toutes les dépendances nécessaires pour créer ce projet. Nous utiliserons le Spring Boot Starter Web.
  • CurrencyConversionBean.java - Le bean pour stocker la réponse que nous voulons envoyer.
  • CurrencyExchangeServiceProxy.java - ce sera le proxy Feign pour appeler le service Forex.
  • CurrencyConversionController.java - Contrôleur Spring REST qui fournit un service de conversion de devises. Il utilisera CurrencyExchangeServiceProxy pour appeler le service Forex.

Outils dont vous avez besoin


  • Maven 3.0+ - outil de construction
  • Votre IDE préféré. Nous utilisons Eclipse.
  • JDK 1.8+

Projet Ready Maven avec des échantillons de code


Le référentiel Github contient tous les exemples de code.

Création d'un projet à l'aide de Spring Initializr


La création d'un microservice avec Spring Initializr est une marche facile.

Spring Initializr est un excellent outil pour créer rapidement vos projets Spring Boot.

Avec l'aide de Spring Initializr, vous pouvez créer une variété de projets.



Les étapes suivantes doivent être suivies pour créer un projet de développement de services Web:

1. Lancez Spring Initializr et tapez ce qui suit:

  • Tapez com.in28minutes.springboot.microservice.example.currencyconversion en tant que groupe.
  • Tapez spring-boot-microservice-currency-conversion comme un artefact.
  • Sélectionnez les dépendances suivantes: Web , DevTools , Feign

2. Cliquez sur Générer un projet .

3. Importez le projet dans Eclipse: Fichier -> Importer -> Projet Maven existant.

N'oubliez pas de lister Feign dans les dépendances.

Création de CurrencyConversionBean


Il s'agit d'un simple bean pour créer une réponse.

 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; } 

Implémentation d'un client REST avec RestTemplate


Le code ci-dessous illustre l'implémentation d'un client REST pour appeler un service Forex et traiter une réponse. Comme vous pouvez le voir, pour effectuer un appel de service simple, vous devez écrire beaucoup de code.

 @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()); } 

Configurer le nom et le port de l'application


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

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

Test de microservices


Lancez l'application Spring Boot en exécutant 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, } 

Création de proxys feints


Feign fournit la meilleure alternative à RestTemplate pour appeler l'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); } 

Nous définissons d'abord un proxy simple:

  • @FeignClient (name = "forex-service" url = "localhost: 8100") - déclare qu'il s'agit d'un client Feign et que l'URL où se trouve le service Forex est localhost: 8100
  • @GetMapping ("/ currency-exchange / from / {from} / to / {to}") - L'URI du service que nous aimerions utiliser

Utilisation de proxys Feign dans un contrôleur de microservice


Passer un appel via un proxy est très simple. Vous le verrez en action dans le code ci-dessous. Tout ce que nous avions à faire était de connecter automatiquement le proxy et de l'utiliser pour appeler la méthode.

 @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()); } 

Activation des clients Feign


Avant de pouvoir utiliser Feign, nous devons l'activer à l'aide de l'annotation @EnableFeignClients dans le package approprié où les proxys clients sont définis.

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

Test d'un microservice à l'aide de 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, } 

Résumé


Nous avons créé deux microservices et établi une connexion entre eux.



Cependant, nous avons codé en dur l'URL de FS vers CCS. Cela signifie que lorsque de nouvelles instances FS sont lancées, nous n'avons aucun moyen de répartir la charge entre elles. Dans la partie suivante, nous activerons l'équilibrage de charge côté client à l'aide du ruban.

Exemple de code complet

/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/fr485094/


All Articles