Микросервисы со Spring Boot. Часть 2. Создание микросервиса Forex

от автора

Это вторая часть серии статей по основам микросервисных архитектур, в которой показывается, как создать микросервис с помощью Spring Boot и заставить его работать с Spring MVC, JPA, Hibernate и H2.

В этой серии статей вы познакомитесь с концепцией микросервисов и узнаете, как создавать микросервисы с помощью Spring Boot и Spring Cloud.

Это руководство поможет вам изучить основы микросервисных архитектур. Мы также начнем рассматривать базовую реализацию микросервиса со Spring Boot.

Мы создадим пару микросервисов и заставим их общаться друг с другом с помощью сервера имен Eureka (Eureka Naming Server) и Ribbon для балансировки нагрузки на стороне клиента.

Это статья входит в серию статей «Микросервисы со Spring Boot»:

  • Часть 1. Начало работы с архитектурой микросервисов
  • Часть 2. Создание микросервиса Forex
  • Часть 3. Создание микросервиса конвертации валют
  • Часть 4. Использование Ribbon для балансировки нагрузки
  • Часть 5. Использование сервера имен Eureka

Вы изучите

  • Как создать микросервис с помощью Spring Boot?
  • Как создать JPA сущность и ресурс?
  • Как заставить Spring MVC, Spring Boot, JPA, Hibernate и H2 работать вместе?

Обзор ресурсов

Forex Service (FS) является поставщиком услуг. Он обеспечивает значения курсов обмена валюты для различных валют. Давайте предположим, что он общается с Forex Exchange и предоставляет текущие значения курсов обмена различных валют.

Пример запроса и ответа показан ниже:

GET to http://localhost:8000/currency-exchange/from/EUR/to/INR

{   id: 10002,   from: "EUR",   to: "INR",   conversionMultiple: 75,   port: 8000, }

Запрос выше возвращает обменный курс евро к INR. В ответе получается, что коэффициент конвертации ConversionMultiple равен 75.

Структура кода проекта

На следующем скриншоте показана структура проекта, который мы создадим.

Некоторые элементы проекта:

  • SpringBootMicroserviceForexServiceApplication.java — класс Spring Boot приложения, созданный с помощью Spring Initializer. Этот класс действует как точка запуска приложения.
  • pom.xml — содержит все зависимости, необходимые для создания этого проекта. Мы будем использовать Spring Boot Starter Web и JPA.
  • ExchangeValue.java — объект, содержащий количество валюты для обмена.
  • ExchangeValueRepository.java — JPA репозиторий для ExchangeValue. Он создан с помощью Spring Data JpaRepository.
  • ForexController.java — Spring REST контроллер, предоставляющий сервис конвертации форекс.
  • data.sql — исходные данные для таблицы exchange_value. Spring Boot выполнит этот скрипт после того, как таблицы будут созданы из сущностей.

Вам понадобятся

  • Maven 3.0+ — инструмент для сборки
  • Ваш любимый IDE. Мы используем Eclipse.
  • JDK 1.8+

Готовый проект Maven с примерами кода

В Github репозитории есть все примеры кода.

Создание проекта с помощью Spring Initializr

Создание микросервиса с Spring Initializr — это легкая прогулка.

Spring Initializr: start.spring.io — отличный инструмент для быстрого создания ваших проектов Spring Boot.

С помощью Spring Initializr вы можете создавать самые разные проекты.

Следующие шаги нужно сделать для создания проекта разработки веб-сервисов:

1. Запустите Spring Initializr и наберите следующее:

  • Наберите com.in28minutes.springboot.microservice.example.forex в качестве группы.
  • Наберите в качестве артефакта spring-boot-microservice-forex-service.
  • Выберите следующие зависимости:

        — Web
        — DevTools
        — Стартер JPA
        — H2
2. Нажмите Generate Project.

3. Импортируйте проект в Eclipse: File -> Import -> Existing Maven Project.

Создание класса Exchange Value

@Entity public class ExchangeValue {      @Id   private Long id;      @Column(name="currency_from")   private String from;      @Column(name="currency_to")   private String to;      private BigDecimal conversionMultiple;   private int port;      public ExchangeValue() {        }       public ExchangeValue(Long id, String from, String to, BigDecimal conversionMultiple) {     super();     this.id = id;     this.from = from;     this.to = to;     this.conversionMultiple = conversionMultiple;   }    public Long getId() {     return id;   }    public String getFrom() {     return from;   }    public String getTo() {     return to;   }    public BigDecimal getConversionMultiple() {     return conversionMultiple;   }      public int getPort() {     return port;   }    public void setPort(int port) {     this.port = port;   }  } 

Важные вещи, на которые стоит обратить внимание:

  • Entity: указывает, что класс является сущностью. Эта аннотация применяется к классу сущностей.
  • Id: Определяет первичный ключ объекта.

Создание JPA-репозитория Exchange Value

/spring-boot-microservice-forex-service/src/main/java/com/in28minutes/springboot/microservice/example/forex/ExchangeValueRepository.java

package com.in28minutes.springboot.microservice.example.forex; import org.springframework.data.jpa.repository.JpaRepository;  public interface ExchangeValueRepository extends      JpaRepository<ExchangeValue, Long>{   ExchangeValue findByFromAndTo(String from, String to); }

Примечания:

1. public interface ExchangeValueRepository extends JpaRepository<ExchangeValue, Long>

расширяет JpaRepository, используя два дженерика: ExchangeValue и Long. ExchangeValue является объектом, которым управляют, а первичным ключом ExchangeValue является Long.

2. ExchangeValue findByFromAndTo (String from, String to)

определяет метод запроса стоимости конвертации из одной валюты в другую.

Создаем ресурс ForexController

/spring-boot-microservice-forex-service/src/main/java/com/in28minutes/springboot/microservice/example/forex/ForexController.java

@RestController public class ForexController {      @Autowired   private Environment environment;      @Autowired   private ExchangeValueRepository repository;      @GetMapping("/currency-exchange/from/{from}/to/{to}")   public ExchangeValue retrieveExchangeValue     (@PathVariable String from, @PathVariable String to){          ExchangeValue exchangeValue =          repository.findByFromAndTo(from, to);          exchangeValue.setPort(         Integer.parseInt(environment.getProperty("local.server.port")));          return exchangeValue;   } }

Примечания:

1. @RestController public class ForexController {

    создает контроллер для предоставления REST сервиса

2. Autowired private Environment environment

    возвращает порт (port) сервера. Это поможет определить, какой экземпляр сервиса возвращает ответ.

3. Autowired private ExchangeValueRepository repository — автоматическое подключение репозитория.

4. ExchangeValue exchangeValue = repository.findByFromAndTo(from, to) — получаем значение курса обмена валют из базы данных.

5. exchangeValue.setPort(Integer.parseInt(environment.getProperty(«local.server.port»)))

    получает атрибут порт (port) из объекта environment и устанавливает его в бин ответа.

Настройка Application Name и несколько других настроек

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

spring.application.name=forex-service server.port=8000  spring.jpa.show-sql=true spring.h2.console.enabled=true

Назначаем порт 8000 для этого приложения и включаем ведение журнала для отладки.

Вставляем некоторые тестовые данные в data.sql

Давайте вставим некоторые тестовые данные, создав файл с именем data.sql. Spring Boot Auto Configuration обеспечивает загрузку этих данных при запуске приложения.

/spring-boot-microservice-forex-service/src/main/resources/data.sql

insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) values(10001,'USD','INR',65,0); insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) values(10002,'EUR','INR',75,0); insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) values(10003,'AUD','INR',25,0);

Тестируем Forex микросервис

GET to http://localhost:8000/currency-exchange/from/EUR/to/INR

{   id: 10002,   from: "EUR",   to: "INR",   conversionMultiple: 75,   port: 8000, }

Далее в этой серии статей:

  • Создание сервиса конвертации валют CCS. Мы создадим простой REST сервис, используя Feign для вызова микросервиса Forex.
  • Использование Ribbon для балансировки нагрузки.
  • Внедрение Eureka Naming Service и подключение FS и CCS через Eureka.

Полный код примера

/spring-boot-microservice-forex-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.forex</groupId>   <artifactId>spring-boot-microservice-forex-service</artifactId>   <version>0.0.1-SNAPSHOT</version>   <packaging>jar</packaging>    <name>spring-boot-microservice-forex-service</name>   <description>Microservices with Spring Boot and Spring Cloud - Forex Service</description>    <parent>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-parent</artifactId>     <version>2.0.0.RELEASE</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.M8</spring-cloud.version>   </properties>    <dependencies>     <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-data-jpa</artifactId>     </dependency>     <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-web</artifactId>     </dependency>      <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-devtools</artifactId>       <scope>runtime</scope>     </dependency>     <dependency>       <groupId>com.h2database</groupId>       <artifactId>h2</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-forex-service/src/main/java/com/in28minutes/springboot/microservice/example/forex/ExchangeValue.java

package com.in28minutes.springboot.microservice.example.forex; import java.math.BigDecimal;  import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id;  @Entity public class ExchangeValue {      @Id   private Long id;      @Column(name="currency_from")   private String from;      @Column(name="currency_to")   private String to;      private BigDecimal conversionMultiple;   private int port;      public ExchangeValue() {        }       public ExchangeValue(Long id, String from, String to, BigDecimal conversionMultiple) {     super();     this.id = id;     this.from = from;     this.to = to;     this.conversionMultiple = conversionMultiple;   }    public Long getId() {     return id;   }    public String getFrom() {     return from;   }    public String getTo() {     return to;   }    public BigDecimal getConversionMultiple() {     return conversionMultiple;   }      public int getPort() {     return port;   }    public void setPort(int port) {     this.port = port;   }  }

/spring-boot-microservice-forex-service/src/main/java/com/in28minutes/springboot/microservice/example/forex/ExchangeValueRepository.java

package com.in28minutes.springboot.microservice.example.forex;

import org.springframework.data.jpa.repository.JpaRepository;  public interface ExchangeValueRepository extends      JpaRepository<ExchangeValue, Long>{   ExchangeValue findByFromAndTo(String from, String to); }

/spring-boot-microservice-forex-service/src/main/java/com/in28minutes/springboot/microservice/example/forex/ForexController.java

package com.in28minutes.springboot.microservice.example.forex; import java.math.BigDecimal;  import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController;  @RestController public class ForexController {      @Autowired   private Environment environment;      @Autowired   private ExchangeValueRepository repository;      @GetMapping("/currency-exchange/from/{from}/to/{to}")   public ExchangeValue retrieveExchangeValue     (@PathVariable String from, @PathVariable String to){          ExchangeValue exchangeValue =          repository.findByFromAndTo(from, to);          exchangeValue.setPort(         Integer.parseInt(environment.getProperty("local.server.port")));          return exchangeValue;   } }

/spring-boot-microservice-forex-service/src/main/java/com/in28minutes/springboot/microservice/example/forex/SpringBootMicroserviceForexServiceApplication.java

package com.in28minutes.springboot.microservice.example.forex;  import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;  @SpringBootApplication public class SpringBootMicroserviceForexServiceApplication {    public static void main(String[] args) {     SpringApplication.run(SpringBootMicroserviceForexServiceApplication.class, args);   } }

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

spring.application.name=forex-service server.port=8000  spring.jpa.show-sql=true spring.h2.console.enabled=true

/spring-boot-microservice-forex-service/src/main/resources/data.sql

insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) values(10001,'USD','INR',65,0); insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) values(10002,'EUR','INR',75,0); insert into exchange_value(id,currency_from,currency_to,conversion_multiple,port) values(10003,'AUD','INR',25,0);

/spring-boot-microservice-forex-service/src/test/java/com/in28minutes/springboot/microservice/example/forex/SpringBootMicroserviceForexServiceApplicationTests.java

package com.in28minutes.springboot.microservice.example.forex;  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 SpringBootMicroserviceForexServiceApplicationTests {    @Test   public void contextLoads() {   }  }

ссылка на оригинал статьи https://habr.com/ru/post/484864/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *