Ocelot API Gateway: Routing & Aggregation & Authentication

Ocelot .Net API gateway

API Gateway, client ile mikro servisler arasında yer alarak bir reverse proxy olarak çalışır. Client tarafından aldığı istekleri bir takım kurallar doğrultusunda ilgili servislere dağıtır. Bu sayede çeşitli güvenlik zaafiyetlerinin önüne geçerken aynı zamanda istemcinin tüm servisler yerine tek bir API üzerinden konuşmasını sağlar. Ocelot Api Gateway aracılığıyla Routing, Request Aggregation, Authentication, Authorization, Rate Limiting, Caching ve Load Balancing gibi çeşitli işlemleri yerine getirebiliriz.

Ocelot .Net API Gateway

Ocelot, .NET Core için geliştirilen bir Api Gateway kütüphanesidir. Bir ASP.NET projesini Api Gateway‘e çevirmek için Ocelot isimli Nuget paketini kurmak gereklidir. Yukarıda da görüldüğü üzere mikro servis endpoint’leri expose olmaksızın client sadece API Gateway ile haberleşmektedir. Bu sayede servis ağının yönetilmesi de kolaylaşmaktadır. Buna ilaveten giriş paragrafında sayılan özelliklere de sahiptir. Ayrıca görseldeki servisler senaryomuzda kullanılacaktır.

Senaryo

Senaryomuzda ürünleri listeleyen bir Product servisi, ürün indirimlerini getiren Discount servisi, ürün kategorilerini barındıran Category servisi ve API Gateway projesi yer alacaktır. Projelerimizi webapi tipinde oluşturup, API Gateway projesine Ocelot Nuget paketini kuralım.

Konuyu pekiştirmek adına Routing, Authentication, Request Aggregation ve Rate Limiting konularına göz atıyor olacağız. Projelerimizi oluşturduktan sonra Controller sınıflarımızı aşağıdaki şekillerde dolduralım.

Görüldüğü üzere Product servisinde Product sınıfı ve statik veri döndüren iki adet action method’u tanımlanmıştır.

Discount servisindeyse yine gerekli tanımlamalar yapılıyor.

Category servisi içinde gerekli tanımlamalar yapıldıktan sonra servisleri ayağa kaldıracağımız portları ayarlayalım. Product servisini :7001, Discount servisini :7002 ve Category servisini de :7003 portunda çalışacak şekilde ayarlayalım.

API Gateway projemizi geliştirelim. Öncelikle Ocelot NuGet paketini kurmamız gerekiyor. Sonrasındaysa Program.cs dosyasına gelerek gerekli ayarlamaları yapalım.

Öncelikle AddJsonFile methoduyla Ocelot konfigürasyonlarını barındıran .json dosyasını ekliyoruz. Sonrasındaysa AddOcelot ile bildirim yapıyoruz ve ardından AddDelegatingHandler ile HttpClient isteklerini Intercept edeceğimizi RequestLogger sınıfıyla bildiriyoruz.

Delegate Handler DelegatingHandler abstract sınıfından türemelidir. Bu sınıf aracılığıyla http isteklerini intercept ederek akışı değiştirebiliriz. Biz örneğimizde loglama yapıyoruz.

Routing

Ocelot konfigürasyonları bir .json dosyasında tutulmaktadır. Gelen isteklerin nereye, ne şekilde iletileceği kurallarıyla diğer tüm özellik bildirimlerini bu dosyadan belirteceğiz. Ayarlamalarımızı yapmak üzere ocelot.json isminde bir dosya oluşturup Route’larımızı belirtelim.

Downstream önekiyle başlayan özellikler gelen isteğin nereye yönlendirileceği, Upstream önekiyle başlayan özellikler ise gelen isteği karşılayacak olan ayarları içermektedir. Buna göre Ocelot API Gateway‘e /products adresinden bir GET isteği gönderildiğinde bu isteğin https://localhost:7001/product adresine yönlendirileceğini belirtiyoruz. Ayrıca GlobalConfiguration özelliğiyle genel ayarları yapıyoruz.

Request Aggregation

Ocelot ile birden fazla servise istek atarak sonucu tek bir istekle birleştirilmiş şekilde alabiliriz. Bunun için Key ve Aggregates özelliklerinden faydalanmaktayız. Konfigürasyon dosyamızı aşağıdaki şekilde düzenleyelim.

Buna göre öncelikle route‘larımızı belirli bir key ile işaretliyoruz. Sonrasındaysa Aggregates dizisi içerisinde verilen key’lerin birleştirilerek hangi adres üzerinden expose edileceğini belirtiyoruz.

Rate Limiting

Ocelot ayrıca rate limit özelliğini de destekler. Upstream istekleri limitleyerek downstream servislerin overload olmasının önleyebiliriz.

Görüldüğü üzere bu özelliği RateLimitOptions özelliğini kullanarak aktifleştiriyoruz.

  • ClientWhitelist: Bu durumdan etkilenmeyecek istemci ip adresleri belirtiliyor,
  • EnableRateLimiting: Özelliği aktifliği ayarlanıyor,
  • Period: Limit ile belirtilen isteklerin ne kadar süre içerisinde yapılabileceği,
  • PeriodTimespan: İstemcinin limiti aşması durumunda ne kadar süre bekletileceği,
  • Limit: Period ile belirtilen süre içerisinde yapılabilecek istek sayısı belirtiliyor.

Response Caching

Ocelot, Ocelot.Cache.CacheManager Nuget paketi aracılığıyla basit bir cache mekanizması da sunar. Özelliği kullanmak için paketi API Gateway projemize kuralım ve Program.cs dosyasında caching bildirimini yapalım.

ocelot.json dosyasında ilgili özelliği ekleyelim.

FileCacheOptions ile TtlSeconds özelliğinde 15 saniye cache yapılacağı belirtilmiştir. Ayrıca konu başında da kullanılan Delegate Handler ile custom caching mekanizmaları oluşturulabilir.

Authentication

Ocelot ile route bazlı Authentication ve Authorization işlemlerini de gerçekleştirebiliriz, bu yazıda sadece Authentication özelliği üzerinde durulacaktır. Kimlik doğrulama işlemi client tarafından gönderilecek olan Token vasıtasıyla gerçekleştirilmektedir.

Bunun için servislerimiz arasına JWT Token üretecek bir Auth servis ekleyelim. Microsoft.AspNetCore.Authentication.JwtBearer NuGet paketini kurduktan sonra Controller sınıfımızı aşağıdaki gibi dolduralım.

Sonrasındaysa kategori servisinde Controller sınıfımızı Authorize attribute’ü ile işaretleyerek Program.cs içerisinde gerekli yetkilendirme ayarlamalarını yapalım. Ayrıca aşağıdaki yetkilendirme ayarlarını API Gateway projesinde de yapmalıyız.

Son olarak ocelot.json dosyasına hem Auth servisini ekleyelim hem de Category servisini yetkilendirmeye tabi tutalım.

Yukarıdaki koda baktığımızda yetkilendirmeyi AuthenticationOptions ile aktif ettiğimizi görüyoruz. AuthenticationProviderKey ile yetkilendirmenin hangi AuthenticateScheme üzerinden yapılacağını belirtiyoruz. Artık Category servisine istekte bulunurken Auth servis üzerinden alacağımız token bilgisiyle istekte bulunabiliriz.

Load Balancing

Yük dengelemeyle artan trafik veya yük sonucu oluşabilecek yoğunluğu dengeleyebiliriz. Bunu sistemin upgrade edilerek scale-up / vertical scaling işlemi yapılması yerine, sisteme yeni sunucuların eklenerek scale-out / horizontal scaling işlemi yapılmasıyla sağlıyoruz.

Scaling Types

Bu dengeleme işleminin nasıl yapılacağı bir takım algoritmalara göre belirlenmektedir.

  • Round Robin: Gelen isteklerin sunucular arasında sırayla dağıtıldığı algoritmadır.
  • Least Connection: Gelen isteklerin en az yoğunlukta olan sunucuya yönlendirildiği algoritmadır.
  • IP Hash: Gelen isteklerin IP adreslerine göre hangi sunucuya yönlendirileceğini belirten algoritmadır.

Discount servisini Dockerize ederek farklı portlarla ayağa kaldırıp Ocelot’un gelen istekleri nasıl dağıttığına göz atalım.

Oluşturduğumuz Dockerfile’ı aşağıdaki gibi dolduralım.

Sonrasındaysa ocelot.json dosyasında Load Balancer ayarlarını yapalım.

Yukarıdaki koda baktığımızda yük dengelemeyi LoadBalancerOptions ile aktif ettiğimizi görüyoruz. Type ile dengelemenin ne şekilde yapılacağını belirtiyoruz. Bu algoritmalar LeastConnection, RoundRobin, NoLoadBalancer veya CookieStickySessions tipinde olabilir. Ayrıca kendi custom load balancer‘ımızı da yazabiliriz. Aşağıda basit bir RoundRobin simüle edilmiştir.

Sonrasındaysa LoadBalancerOptions özelliğini aşağıdaki gibi düzelterek yazdığımız custom load balancer‘ı kullanabiliriz.

Görüldüğü üzere mikro servis veya servis odaklı mimarilerde Ocelot bir çok işlemi efektif şekilde yerine getiriyor. Geliştirilen proje dosyalarına buradan ulaşabilirsiniz.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.