Spring Cloud Gateway ile API Yönlendirme ve Filtreleme

Gökhan Pehlivan
AgeSA İş Teknolojileri
6 min readApr 1, 2024

API Gateway, mikroservis mimarisinde gelen istekleri yönetmek, filtrelemek ve dağıtmak için kullanılan bir araçtır. Tek bir giriş noktası sağlayarak, istemcilerin farklı mikro servislere erişimini kolaylaştırır. Aynı zamanda güvenlik, yetkilendirme, hata yönetimi ve istek yönlendirme gibi işlevleri de sağlar.

Neden API Gateway kullanmalıyız?

API Gateway, istemcilerin mikro servislere / uygulamalara erişim için merkezi bir giriş noktası görevi görür. Servis uygulamalarınızın sayısı arttıkça iletişimi yönetmenin karmaşıklığı da artmaktadır. İstemcilere her servis için url ve port bilgilerinin paylaşımı ve yönetmesi zorlaşacaktır. Aslında API Gateway tam olarak bu noktada servisleriniz ile istemciler arasında bir ara yüz oluşturarak bu karmaşıklığı gidermektedir. İstemcilerinize vereceğiniz tek bir Gateway adresi ile tüm isteklerinizi, servislerinize / uygulamalarınıza yönlendirmeden önce ve sonra bazı kontroller yaparak yönetebilme imkanına sahip olmaktayız.

Bu kontroller ile Authentication, Authorization, Caching, Load Balancing ve Logging gibi özellikler ekleyebilir, request ve response’larımızı yönetebiliriz.

Bu yazıda sizlere bir Spring Cloud modülü olan Spring Cloud Gatewayden bahsetmek istiyorum.

Spring Cloud Gateway, Spring Boot, Spring WebFlux ve Project Reactor ile hazırlanan bir API Gateway aracıdır. Ayrıca Spring MVC ile WebFlux ve Reactor kullanmadan Jetty ve Tomcat gibi Servlet’ler ile birlikte de kullanılmaya başlanmıştır. Bunu kullandığımızda async ve reactor yapıları geçerli olmayacaktır.

Spring Cloud Gateway servislerimize istemcilerden (clients) gelen istekleri alıp gerekli mikro servisin ilgili endpoint’ine yönlendirecektir. Yönlendirme öncesi ve sonrası filtreler ekleyebiliriz. Örneğin gelen tüm istekler için Gateway üzerinden geçerken “correlation-id” ekleyerek servisler arası iletişimi izleyebiliriz. Servislerden dönen response mesajlarında status kontrolü yaparak istemciye dönmeden önce ek olarak header ve parametreler ekleyebiliriz.

Spring Cloud Gateway, API’lere yönlendirme için etkili bir yol sağlamayı ve onlara güvenlik, izleme / ölçümler (monitoring / metrics) ve dayanıklılık (resiliency) gibi özellikler sağlamayı amaçlamaktadır.

Temel Kavramlar

Route : Bir ID, hedef URI, predicate ve filtreler tarafından tanımlanan Gateway’in temel yapı taşıdır.

Predicate : Java 8 Function Predicate’leridir. Headers ya da parametreler gibi HTTP isteğindeki herhangi bir özelliği eşleştirmenizi sağlamaktadır.

Filter: Bir HTTP isteğini göndermeden önce veya sonra request ve response içeriğini değiştirmek için kullanılır.

Bir istek gönderildiğinde ilk olarak Gateway Handler Mapping bir route ile eşleştiğini belirlerse, Gateway Web Handler’a gönderilir. İstek gönderilmeden önce ve gönderildikten sonra filter’lar çalıştırılır. Filtreler ile Gateway üzerinden istekler yönlendirilirken request ve response’ları değiştirmek için filtreler uygulayabilirsiniz. Filtreler, loglama, kimlik doğrulama, caching gibi görevleri yerine getirebilir.

Kurulum

Spring Cloud Gateway uygulamanıza eklemek için “spring-cloud-starter-gateway” dependency olarak projenize eklemeniz gerekmektedir.

Route (Rota) Oluşturma

application.yml

id: Rota benzersiz(unique) bir id değerine sahip olmalıdır.

uri: Hedef(target) microservice URI.

predicates: Tanımlanan “uri” adresine yönlendirmeden önce kontrol etmek istediğiniz koşul ya da koşullar tanımlanır.

Route Predicate Factories

Gelen isteklerin hangi adrese yönlendirileceğini belirlemek için kullanılan kuralları tanımlamak için kullanılır. Örneğin Header, Path ya da Query parametrelerini bir rota ile eşleştirme sağlanarak hedef adrese yönlendirme yapılır.

Path: İsteğin URL path’ine göre yönlendirme yapar.

application.yml

Bu rota, istek path’inde örneğin, /category/1 veya /category/phones olması durumunda eşleşir. İsteği “uri” adresinde belirlenen servise yönlendirir.

Query: İsteğin sorgu parametrelerine göre yönlendirme yapar.

application.yml

Bu rota, gelen request’in Query parametresinde “lang, en” olması durumunda isteği “uri” adresinde belirlenen servise yönlendirir.

Header ve Method: Belirli bir HTTP başlığına ve Method’a göre yönlendirme yapar.

application.yml

Bu rota, gelen request’in, X-Request-Id adında bir başlığa sahip olması ayrıca GET ya da POST HTTP Method tipinde olması durumunda eşleşecektir.

Filters:

Gelen istekleri (requests) ve istek yanıtlarını (outgoing HTTP response) işlemek, değiştirmek ve düzenlemek için kullanılmaktadır.

Spring Cloud Gateway’de Filter yapısı ile gelen her isteği etkileyecek genel filtreler (Global Filters) oluşturabilirsiniz. Belirli rota ve istekler için de filtreleme kullanılabilmektedir. Ayrıca request ve response değiştirebilir (mutate) ve bir zincir (chain) oluşturarak filtrelerinizi sırasıyla request ve response esnasında çalıştırabilirsiniz.

Spring Cloud Gateway, request ve response filtrelemek için birçok hazır (built-in) “filter factory” sınıfı sunmaktadır.

Bunlardan bazıları:

AddRequestHeader: Gelen request’e belirli bir başlık ekler.

AddResponseHeader: Hedef hizmetten gelen response’a belirli bir başlık ekler.

RewritePath: İstek URL’sini yeniden yazarak yönlendirme yapar.

Retry: Belirli koşullarda request’i yeniden denemek için kullanılır.

RequestRateLimiter: Belirli bir hızda request’leri kabul etmek için kullanılır.

AddRequestParameter: Gelen request’e belirli bir sorgu parametresi ekler.

ModifyRequestBody: İstek gövdesini (request body) Gateway tarafından gönderilmeden önce değiştirmek için kullanılır.

ModifyResponseBody: Yanıt gövdesini (response body) istemciye geri gönderilmeden önce değiştirmek için kullanılır.

Bu örnekte, Gateway adresimize örneğin, “http://myapigateway.com/category/1” olarak bir istek geldiğini varsayalım, “/category/**” predicate’i olduğu için aşağıdaki microservice-1 olarak tanımlı rota ile eşleşecektir ve “uri” alanında belirlenen servisimize yönlendirilecektir. Yönlendirilecek olan adresimiz, “http://backend-service/category/1” olacaktır.

Bu yönlendirme yapılırken filter’lar eklenmiştir. AddRequestHeader ile yeni bir header eklenerek servisimize yönlenecektir. Ayrıca AddRequestParameter ile yeni bir parametre eklenir, RemoveResponseHeader ile response içeriğinden “Another-Header” başlığı kaldırılır. Son olarak Retry ile GET ve POST işlemleri için yönlendirdiğimiz servisimizden “BAD_GATEWAY” response statusu alınması durumunda 3 kez tekrar istek yapmayı deneyecektir.

Example:

application.yml

Gateway, gelen isteği ilgili servisimize yönlendirirken, header ve parametre ekleyecektir. Servisimizden dönen response içeriğinden ise bir header değeri kaldıracaktır.

AddRequestHeader: Eşleşen tüm request’ler için isteğin başlıklarına X-Custom-Header başlığını ekler.

RemoveResponseHeader: Gateway, istemciye geri göndermeden önce cevap gövdesinden (response body) Another-Header kaldıracaktır.

AddRequestParameter: Eşleşen tüm request’ler için request’in sorgu parametresine (query string) lang, tr parametresini ekler.

Retry: Belirli koşullarda request’i yeniden dener.

retries: Request’in tekrar deneme sayısı.

statuses: HttpStatus kullanılarak, yeniden denenmesi gereken HTTP durum kodları.

methods: Yeniden denenmesi gereken HTTP metotları.

Global Filters: Tüm istekler (requests) için çalışmasını istediğiniz özel filtreler oluşturabilirsiniz. Bir GlobalFilter oluşturmak için GlobalFilter arayüzünü uygulamalısınız. Bir istek bir rota (route) ile eşleştiğinde, Gateway GlobalFilter’ın tüm örneklerini bir filtre zincirine (filter chain) ekler. Bu filtre zinciri, getOrder() yöntemini uygulayarak ayarlayabileceğiniz org.springframework.core.Ordered arayüzüne göre sıralanır.

Order, filtrenin zincir içindeki sırasını belirler. Daha düşük bir order değeri, filtrenin daha önce çalıştırılmasını belirtir. Yani, önce düşük order değerine sahip filtreler çalışır, sonra yüksek order değerine sahip filtreler çalışır. Örneğin, -1 order değeri 0 order değerinden daha önce çalışır.

Aşağıda tüm isteklerde loglama yapabileceğimiz basit bir GlobalFilter örneği bulunmaktadır. İstek yapılmadan önce isteğin yapıldığı “path” log’a yazdırılır. Gelen cevap (response) ile HTTP status kodu alınarak log’a eklenir.

Example:

Gateway’e bir istek yapıldığında Pre ve Post Logging Filter’ın çalıştığını görebiliriz.

Sonuç olarak, Spring Cloud Gateway ile istemcilerinizden (clients) gelen tüm istekleri tek bir noktadan yönetebilir, istek (request) ve cevap (response) özelliklerinizi değiştirebilir, özel filtreler oluşturarak sırayla çalıştırabilirsiniz.

Ayrıca, Spring ekosistemiyle entegrasyonu sayesinde, diğer Spring projeleriyle sorunsuz bir şekilde çalışabilir ve geniş bir topluluk tarafından desteklenir.

Kaynak: https://cloud.spring.io/spring-cloud-gateway/reference/html/#gateway-starter

--

--