Swagger&Ocelot = SwaggerForOcelot
Merhaba arkdaşlar, yeni bir ülkeye taşınma adapte olma vs derken yazı yazmayalı uzun süre olmuş. Bugünkü yazımda, yakın bir zamanda tecrübe etmiş olduğum SwaggerForOcelot kütüphanesinden bahsetmek istiyorum.
Yakın zamanda danışmanlık yaptığım firmada, monolithic olan bir projenin kendi başına çalışabilecek modülleri ayrılmaya başlamıştı. Bu servisleri bir araya toplamak için Api Gateway olarak Ocelot tercih etmiştik. Aynı şekilde rest api dokümantasyonu için, openapi implementasyonu olan oldukça populer Swagger kullanılıyordu.
Evet servisler ayrıldı. Daha sonra Ocelot vasıtasıyla tek bir enpoint üzerinden kullanılmaya başlandı. Ancak dokümantasyon hala ayrı duruyordu. Test edilmek istendiğinde(dokuman ihtiyaç olunan durumlarda) yine api’nin kendi endpoint’i bilinmesi gerekiyordu.
Öncelikle servislerin kendi tarafında oluşturalan json dosyalarını birliştirme üzerinden yoğunlaştık. Bu esnada kullanabileceğimiz bir kütüphane var mı diye baktığımızda da SwaggerForOcelot kütüphanesine denk geldik.
Hikaye kısmını geçtiysek artık başlayabiliriz…
Nedir SwaggerForOcelot
SwaggerForOcelot, birbirinden bağımsız iki mükemmel proje olan Ocelot ve Swashbuckle.AspNetCore kütüphanelerinin gücünü birleştiriyor. Kısaca üzerlerinden geçecek olursak;
Swagger&Swashbuckle.AspNetCore: Swagger, servis endpointlerimiz için open api standartlarına bağlı kalarak dokumantasyon oluşturan bir dokumantasyon tool’u. Üzerinde yazılmış o kadar çok yazı olduğu için bir yenisini de ben eklemedim 😊 Neyseki .net 5 ile birlikte bu projeye built-in olarak geliyor. Detaylar için https://swagger.io/tools/ adresini inceleyebilirsiniz. Swashbuckle.AspNetCore ise swagger implementasyonuna ek olarak bize apilerimizi test etmemiz için bir UI sağlar. Bu sayede bir yandan apilerimizi yazarken diğer yandan dokumantasyonumuz canlı kalır.
Ocelot: Ocelot, .Net ekosistemi üzerinde çalışan bir api gateway’dir. Ocelot, Http ile konuşabilen herhangi bir app ile iletişim kurabilmektedir. Detaylar için buradaki yazıma alayım.
Günüzün konusu olan SwaggerForOcelot ise yukarıda bashettiğimiz 2 projeyi bir araya getirmemize destek oluyor. Yani artık api dokümantasyonlarımız da gateway projemizde yer alıyor. Temelinde servis tarafında swagger için oluşturulan json dosyalarını Ocelot ayarlarımıza göre aggregate ediyor diyebiliriz.
Lafı fazla uzatmadan örnek projeye geçiyorum.
Örnek projemiz için SwaggerOcelot adında bir blank solution açıp SwaggerOcelot.Catalog ve SwaggerOcelot.Order adında .net5 web api projesi ekliyorum. SwaggerforOcelot imlementasyonu için SwaggerOcelot.Gateway projesini ekliyorum. Proje vs2019, windows ortamında geliştiriyorum.
Not: Projelerin .net5 olmasının tek sebebi swagger implementasyonlarının built-in olarak gelmesi. Tek yapamanız gereken, Enable OpenAPI support kutucuğunun seçili olduğunuzdan emin olmanız.
Catalog projesi için CatalogController, Order projesi için OrderController ekliyorum. Bunun ile birlikte sadece get methodu ekleyip order ve catalog listesini dönürüyorum.
Not: Ek olarak gateway projesini için 5000, Order projesi için 5001, son olarak da Catalog projesi için 5002 portunu expose ediyorum.
Gateway projesinin implementasyonuna geçmeden önce Catalog ve Order projerini ayağa kaldırıp test ettiğimizde aşağıdaki gibi sonuç alıyorum. Yani elimizde 2 tane swagger enpoint’i var. Yazı sonunda tek bir endpoint altında toplamayı umuyoruz :)
Evet sıra geldi gateway implementasyonuna. Öncelikle aşağıdaki paketleri projemize yüklüyoruz.
Ocelot:Api gateway implementasyonu için gerekli.
MMLib.SwaggerForOcelot: Swashbuckle.AspNetCore ve Ocelot projelerini birleştirmek için kullanacağız. (Yazımızın konusu)
MMLib.Ocelot.Provider.AppConfiguration: Configuration bilgilerini appconfig dosyasından almak için gerekli. (Ayrıca service discovery için Consul, eureka gibi tool’lar kullanıyorsanız, gerekli kütüphaneleri ekleyip ilerleyebilirsiniz.)
Öncelikle ana dizine OcelotConfiguration adında bir klasör ekliyorum. Configuration ile ilgli dosyalarımı buraya ekliyorum. Bunuda program.cs içerisnde host ayağa kalkarken belirtiyorum. Bunun için IConfigurationBuilder için yazılmış AddOcelotWithSwaggerSupport extension methodundan yararlanıyorum.
Daha sonra appsettings.json içerisinde servislerimizin DownStreamPath’lerini ayarlıyoruz. Catalog için 5002, order için 5001 kullandığımızı önceden belitmiştik. Servis için isimlendirmeler size kalmış ve diğer yapacağız konfigurasyonlarda bunları kullanacağız.
Sıra geldi konfigürasyon ayarlarımızı yapmaya. Konfigurasyon dosyalarımız önceden belirttiğimzi gibi OcelotConfiguration altında toplamamız gerekiyor. Tüm konfigürasyonları tek bir dosya içinde yapabilceğiniz gibi bunları ayırabilirsinizde. (SRP’den yola çıkarak, ben bu yoldan ilerleyeceğim)
Adım adım ilerleyecek olursak
Adım 1; ocelot.SwaggerEndpoints.json dosyası oluşturuyorum. Burada servisler için swagger endpoint(servis tarafında oluşan json endpoint’i) bilgisini belirtiyoruz. Son hali aşağıdaki gibidir.
Adım 2; global ayarlarımızı yapmak ocelot.global.json dosyasını oluşturuyorum. Gateway url ile birlikte ServiceDiscoveryProvider olarak AppConfiguration paketini kullanacağımı belirtiyorum.
Adım 3; ocelot.catalog.json dosyasını ekliyorum. Burada gateway tarafında gelen requestin servis tarafında nasıl ilişkilendireceği ile ilgili ayarlar yapılıyor. Burada değinmek istediğim şey; paketin eksik noktalarından biri olarak sadece tek bir path belirtebiliyorsunuz. Dosyamıza görüp üzerinde konuşabiliriz.
Yukarıda da göreceğiniz gibi gateway tarafında catalog-gate sonrası gelen request catalog tarafında api/{everything} olarak gececek. SwaggerKey ve ServiceName için belirlediğimiz isimleri burada doğru eşleştirmemiz gerekmektedir.
Adım 4; ocelot.order.json dosyasını oluşturup konfigürasyonları yapıyorum.
Son olarak statup.cs içinde tanımlarımızı yapmamız gerekiyor. Öncelikle ConfigurationServices içerisinde Ocelot, AppConfiguration ve SwaggerforOcelot servisleriniregister ediyoruz. Akbinde Configure içerisinde SwaggerForOcelotUI ve Ocelot middleware lerini tanımlıyoruz.
Artık projelerimizi multiple olarak seçip ayağa kaldırdığımızda neler olduğuna bakabiliriz. Gateway projemizi kontrol edecek olursak;(http://localhost:5000)
Gördüğünüz gibi select defination kısmında artık 2 api’ geliyor. Catalog için test ettiğimizde sonuç aşağıdaki gibidir.
Aynı şekilde defination kısmından Order api seçip test ettiğimizde sonuç aşağıdaki gibi olacaktır.
Sonuç
Mevcutta kullandığım ve oldukça hoşuma giden kütüphaneden bahsettim. Bu konfigurasyonlar dışında ocelot tarafındaki tüm özellikleri(Rate Limiting, Caching, Authontication/Authorization ) kullanmak ile birlikte swagger tarafında herhangi bir özellikten de ödün ödün vermiyorsunuz.
Projenin kodlarına github adresimden ulaşabilirsiniz.
Bir sonraki yazıda görüşmek üzere, sağlıcakla kalın.