Esta es la tercera parte de una serie de artículos sobre los conceptos básicos de las arquitecturas de microservicios, en los que aprenderá cómo crear un microservicio para la conversión de divisas.
En esta serie de artículos, se familiarizará con el concepto de microservicios y aprenderá a crear microservicios utilizando Spring Boot y Spring Cloud.
Esta guía lo ayudará a aprender los conceptos básicos de las arquitecturas de microservicios. También comenzaremos a ver la implementación básica de microservicios con Spring Boot.
Crearemos un par de microservicios y haremos que se comuniquen entre sí utilizando los servidores de nombres Eureka (Eureka Naming Server) y Ribbon para equilibrar la carga en el lado del cliente.
Este artículo es parte de la serie Spring Boot Microservices:
Aprenderás
- Cómo crear un microservicio usando Spring Boot.
- Cómo usar RestTemplate para crear un servicio REST.
- Cómo usar Feign para crear un servicio REST.
- Beneficios de Fingir sobre RestTemplate.
Resumen de recursos
El Servicio de Conversión de Moneda (CCS) puede convertir muchas monedas a otra moneda. Utiliza el servicio Forex para obtener los valores actuales de cambio de divisas. CCS es un consumidor de servicios.
A continuación se muestra un ejemplo de una solicitud y respuesta:
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 solicitud anterior le permite determinar el valor de 10.000 euros en rupias indias.
El monto total calculado es de 750,000 INR. El siguiente diagrama muestra la relación entre CCS y FS.

Estructura del código del proyecto
La siguiente captura de pantalla muestra la estructura del proyecto que crearemos.

Algunos elementos del proyecto:
- SpringBootMicroserviceCurrencyConversionApplication.java es la clase de aplicación Spring Boot creada con Spring Initializer. Esta clase actúa como el punto de inicio de la aplicación.
- pom.xml : contiene todas las dependencias necesarias para crear este proyecto. Utilizaremos la Web de inicio de Spring Boot.
- CurrencyConversionBean.java : el bean para almacenar la respuesta que queremos enviar.
- CurrencyExchangeServiceProxy.java : este será el Feign Proxy para llamar al servicio Forex.
- CurrencyConversionController.java : controlador Spring REST que proporciona un servicio de conversión de moneda. Utilizará CurrencyExchangeServiceProxy para llamar al servicio Forex.
Herramientas que necesitas
- Maven 3.0+ - herramienta de compilación
- Tu IDE favorito. Usamos Eclipse.
- JDK 1.8+
Proyecto Ready Maven con muestras de código
El repositorio de Github tiene todos los ejemplos de código.
Crear un proyecto usando Spring Initializr
Crear un microservicio con Spring Initializr es una caminata fácil.
Spring Initializr es una gran herramienta para crear rápidamente sus proyectos Spring Boot.
Con la ayuda de
Spring Initializr, puede crear una variedad de proyectos.

Se deben seguir los siguientes pasos para crear un proyecto de desarrollo de servicios web:
1. Inicie Spring Initializr y escriba lo siguiente:
- Escriba com.in28minutes.springboot.microservice.example.currencyconversion como un grupo.
- Escriba spring-boot-microservice-currency-conversion como un artefacto.
- Seleccione las siguientes dependencias: Web , DevTools , Fingir
2. Haga clic en
Generar proyecto .
3. Importe el proyecto a Eclipse: Archivo -> Importar -> Proyecto Maven existente.
Recuerde enumerar
Fingir en las dependencias.
Crear CurrencyConversionBean
Este es un bean simple para crear una respuesta.
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; }
Implementación de un cliente REST con RestTemplate
El siguiente código muestra la implementación de un cliente REST para llamar a un servicio de Forex y procesar una respuesta. Como puede ver, para realizar una llamada de servicio simple, necesita escribir mucho 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 el nombre y el puerto de la aplicación
/spring-boot-microservice-currency-conversion-service/src/main/resources/application.properties spring.application.name=currency-conversion-service server.port=8100
Prueba de microservicio
Inicie la aplicación Spring Boot ejecutando 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, }
Creando poderes fingidos
Feign ofrece la mejor alternativa a RestTemplate para llamar a la 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); }
Primero definimos un proxy simple:
- @FeignClient (name = "forex-service" url = "localhost: 8100") - declara que este es un cliente Feign, y la URL donde se encuentra el servicio Forex es localhost: 8100
- @GetMapping ("/ currency-exchange / from / {from} / to / {to}") - El URI del servicio que nos gustaría usar
Uso de Feign Proxies en un controlador de microservicio
Hacer una llamada a través de un proxy es muy simple. Verá esto en acción en el siguiente código. Todo lo que teníamos que hacer era conectar automáticamente el proxy y usarlo para llamar al 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()); }
Habilitar a los clientes de Fingir
Antes de que podamos usar Feign, debemos habilitarlo usando la anotación @EnableFeignClients en el paquete apropiado donde se definen los proxies del cliente.
@SpringBootApplication @EnableFeignClients("com.in28minutes.springboot.microservice.example.currencyconversion") @EnableDiscoveryClient public class SpringBootMicroserviceCurrencyConversionApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMicroserviceCurrencyConversionApplication.class, args); } }
Probar un microservicio usando Fingir
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, }
Resumen
Creamos dos microservicios y establecimos una conexión entre ellos.

Sin embargo, codificamos la URL de FS a CCS. Esto significa que cuando se lanzan nuevas instancias de FS, no tenemos forma de distribuir la carga entre ellas. En la siguiente parte, habilitaremos el equilibrio de carga del lado del cliente mediante la cinta de opciones.
Código de ejemplo 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 /> </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() { } }