Feign Client (Open Feign) Kullanarak Servisler Arası İletişim Kurmak

Metin Alnıaçık
3 min readMay 8, 2021

--

Spring Boot uygulamalarında, bir servisten başka bir servise istek göndermek istediğimizde RestTemplate sınıfını kullanırız. Konunun kolay anlaşılabilmesi için direkt olarak örneğe geçiyorum. İki tane Spring Boot uygulamamız var. Bu servislerden birincisi vergilendirme hesaplamalarını yapıyor. Diğer servis ise bunun ekranda görüntülenmesi ile ilgili işlemleri yapıyor.

Calculation-Service’inde, Calculation-Controller isimli bir sınıf mevcuttur.

CalculationController sınıfındaki endpoint’leri kullanacak olan servis Presentation-Service’idir.

NOT:
Presentation-Service, http://localhost:8080
Calculation-Service, http://localhost:8081
IP ve port bilgileri ile ayağa kaldırılmıştır.

İki servis ayağa kaldırıldığında http://localhost:8080/300/lux adresine bir istek attığımızda cevap aşağıdaki gibi olacaktır.

Product Price: 300.0 — — Product Type: lux — — Total Price: lux — — Total Price: 375.0

Yukarıdaki işlemin nasıl gerçekleştiğinden bahsedelim. Öncelikle Presentation-Service’e ürün fiyatı ve ürün tipini girerek istek atıyoruz. Vergi hesaplamalarını Calculation-Service yaptığı için Presentation-Service, Calculation-Service’e istek gönderir. Önce Calculation-Service hesapladığı değeri Presentation-Service döner, Presentation-Service’de dönen değer üzerinde gerekli işlemleri yapar ve cevabı döner.

Servisler arası istek gönderme ve cevap alma işlemini tam olarak yapabildiğimize göre neden Feign Client gibi bir şeye ihtiyaç duyuyoruz?

  • Calculation-Service, Presantition-Service içerisindeki bir servis gibi tanımlanır. Bu hem kullanımı kolaylaştırır hem de kodu daha temiz hale getirir.
  • Calculation-Service ile bilgiler ortak bir yerden yönetilir. Örneğin: Calculation-Service’in IP ve port bilgileri gibi.
  • Calculation-Service’in hangi endpoint’leri kullandığımızı bu kısımdan kolayca takip edebiliriz.
  • RestTemplate sınıfına ihtiyacımız yoktur.

Kodumuzu Feign Client eklenmiş haline göre güncelleyelim.

  • Presentation-Service, FeignClient üzerinden istek göndereceği için pom.xml dosyasına ilgili bağımlılıklar eklenir.
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
  • Main metodumuzun olduğu PresentationServiceApplication sınıfına @EnableFeignClients anotasyonu eklenir.
  • Aşağıdaki gibi CalculationService adında bir interface eklenir.
  • Presentation-Service’deki PresentationController sınıfında birkaç güncelleme yapmamız gerekecektir.

CalculationService’i inject ediyoruz. Daha sonra 12. satırda CalculationService’in showTotalPrice metodunu çağırıyoruz. Bu metot Feign Client üzerinden Calculation-Service’e istek gönderir. Dönen değeri totalPrice değişkenine atarız.

Kod kalitemizi bir çok yönden baya artırdık. Feign Client ile ilgili vereceğim bilgi bu kadardı.

BONUS: Eureka (Service Discovery) ile Feign Client’ı beraber kullanmayı göreceğiz.

Eureka, servislerin IP ve port bilgilerini soyutlamamızı sağlar. Örnek olarak, Calculation-Service’si http://localhost:8081 adresi üzerinden hizmet vermektedir. Portu 8081 den 8082 olarak değiştirdiğimizde client durumda olan Presentation-Service çalışmayacaktır.

Bu yazımızda Eureka ile ilgili detaylara girmeyeceğiniz. Eureka Server ile ilgili yazıma aşağıdaki bağlantı adresinden ulaşabilirsiniz.

Yeni bir Spring Boot (Eureka Server) uygulaması oluşturuyoruz.

  • pom.xml dosyasına aşağıdaki bağımlılıklar eklenir.
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
  • Main metodunun bulunduğu DiscoveryServiceApplication sınıfına @EnableEurekaServer anotasyonu eklenir.
  • application.properties dosyasına ilgili bilgiler girilir.
server.port=8761
eureka.instance.hostname=localhost
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false

Discovery Server’a kayıt etmek istediğimiz tüm client’ların main metodu bulunan sınıflarına @EnableDiscoveryClient anotasyonu eklenir.

Client’ların pom.xml dosyalarına aşağıdaki eklemeler yapılır.

<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>2020.0.2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

Üç projeyi beraber ayağa kaldırdıktan sonra http://localhost:8761/ adresine girdiğimizde Eureka Dashboard’a ulaşırız. Bu kısımda hangi client’ların ayakta olduğunu görebiliriz.

Calculation ve Presentation Servislerinin her ikisinin de ayakta (durumları UP) olduğunu görüyoruz.

Presentation-Service’deki CalculationService interface’indeki @FeignClient anotasyonundaki url bilgisini kaldırıyoruz. Bu sayede istek geldiğinde Eureka servis client adından IP ve port bilgilerini verecek ve Calculation-Service’e yönlendirecektir.

İlgili projelere aşağıdaki linklerden ulaşabilirsiniz.

Eureka Server: https://github.com/mtnaln/eureka-server-for-feign-client-example

Presentation Service: https://github.com/mtnaln/presentation-service-for-feign-client-example

Calculation Service: https://github.com/mtnaln/calculation-service-for-feign-client-example

İyi günler,
Bol kodlamalar :)

--

--