ASP.NET MVC Swagger ile Redoc Kullanımı — (Projem Web API değilse?)

Kerem Alincak
Kodcular
Published in
8 min readDec 8, 2019

Merhabalar, öncelikle bu benim ilk yazım. Umarım çok faydalı bir yazı olur. Kendim adına tecrübe etmediğim veya iyi bilmediğim konuları yazmak istemiyorum. Uzun bir çalışma sonucunda bir yazı yazmak istedim.

Yazının içeriği Swagger ile Redoc kullanımı ama ek olarak API projesi olup, Web API olmayan bir proje için Swagger kullanımını da göreceğiz. Uzun bir zaman diliminde bu geçişi tamamladım. Yaşadığım tecrübeleri aktarmak istiyorum.

Konu başlıkları

  • Temel amaç
  • Giriş
  • Peki proje API ama neden Web API değil?
  • Projeniz Web API değilse
  • Local IIS ile çalışmak
  • Swagger’ı projemize ekleyelim
  • *Redoc kullanımı
  • **Redoc’u çalışır hale getirme
  • *Dokümanın detaylı oluşturulması
  • *1 — Controller ve modellerin eklenmesi
  • *2 — SwaggerConfig ufak düzeltmeler
  • *3 — [“ISchemaFilter” kullanımı] Değişkenlerin “Gizlenmesi” ve [FromBody] için “nullable” ve “defaultValue”
  • *4 — [“IOperationFilter“ kullanımı] “ContentType”, “SchemaOneOf” ve [FromUri] için “Default value” ve “Nullable”
  • *5 — [IDocumentFilter kullanımı] genel bilgiler, iletişim bilgileri, logo, güvenlik, etiket gruplama ve etiket açıklamaları
  • *6 — IncludeXmlComments kullanımı
  • *7 — SwaggerResponse kullanımı
  • HttpStatus ve Route kullanımı

Temel amaç

Swagger ile Redoc kullanımı için karşılaştığım problemleri nasıl çözdüğüm olacaktır.

Giriş

Bir web projesinin API tarafina da bakiyordum. Biliyoruz ki her API’nin dokümanı oluyor. Projenin API dokümanı, zamanında bir Word dokümanı olarak yazılmış. Bu API dokümanı konusunda bazı kullanılabilecek araçlar var. Bunlardan birisi ASP.NET için Swagger. Yalnız bu araç için bir Web API projesine ihtiyaç var. Proje Web API olmadığı için bunun yöntemi kendinizin elle JSON veya YAML olarak yazmanızdır. Yazdıktan sonra Swagger araçları ile dönüştürmelisiniz.

Bu yönteme başlanılmış ama yarıda kalmış. Normal karşılarım, zamanında yapmaya çalışmışlar ama Web API olmadığı için görevi üstlenenler sonunu getirememişler. Küçük takımlar için; başka işlerin araya girmesi, zamanın kısıtlı olması gibi gibi durumları göz önüne alırsak bu konular geri planda kalabilir.

Peki proje API ama neden Web API değil?

Zamanında Web API olmadan önce proje normal bir Web projesi olarak yazılmıs. ActionResult, html sayfası dönmek yerine JSON dönülmüş. Proje yoluna API gibi devam etmiş.

Projeniz Web API değilse

Dikkat: Bu işlem sadece Web API olmayan projeler için. Eğer projeniz Web API ise bu adımı geçiniz.

Öncelikle API’niz Web API değilse bunu Swagger için ayarlarını yapalım. Çünkü, Swagger için bunu yaptıktan sonra Web API olan veya olmayan için aynı adımlar izlenecek.

“WebApiConfig” Dosyasını ekleyin. Eklediğiniz dosyayı “Application_Start” içinde çağırın.

“GlobalConfiguration.Configure(WebApiConfig.Register);”

Biliyorsunuz normal durum için “Controllers” klasörümüz oluyor. Web API için(Swagger’ın kullanması için) kendime ayrı klasör oluşturdum. İsmini “DocumentationControllers” olarak ekledim.

Artık Swagger ile görünmesini istediğimiz ayrı bir Controller yerimiz burada olacak. Artık asıl anlatmak istediğim Swagger ile Redoc çalışmasına geçebiliriz.

Local IIS ile çalışmak

Testlerimi daha hızlı yapmak için projemi Local IIS ile çalışacak hale getirdim. Eğer bunu yapmazsanız Swagger testleri için sürekli projeyi çalıştırmak zorunda kalırsınız.

Adım adım;

  • Windows arama kısmına Turn Windows features on or off yazarak ilgili ekrana gidin.
  • Internet Information Services>World Wide Web Services>Application Development Features kısmına gidin.
  • Kendi ASP.NET(örn. benim ASP.NET 4.8'di) sürümünüz olan kısmı seçili hale getirip OK diyin.
  • Şimdilik en kısa yoldan yani proje içinden yapalım. Projenizi kapatıp yönetici olarak tekrar açın.
  • Projeye sağ tıklayıp Properties diyin. Web>Servers kısmında IIS Express seçili olacaktır. Onu Local IIS yapın.
  • Project Url kısmına kullanmak istediğiniz url’i yazın. Benim şuan için “http://localhost/api” yeni yapanlar için http sonrası localhost olarak kalsın. Yoksa başka ayarlar yapmak gerekebilir. Kısacası şimdilik benim yaptığım gibi yapabilirsiniz.

Swagger’ı projemize ekleyelim

NuGet ile projeye “Swashbuckle” paketini ekleyin. “Swashbuckle.Core” ile devam ederseniz, “SwaggerConfig” dosyasını manuel eklemek zorunda kalırsnız.

Config dosyası gelecektir

En temel hali ile Swagger çalışır hale gelecektir. Henüz bir Controller eklemedik. “ http://localhost/api/swagger/ui/index

Artık bu dokümanın süslenmesi kaldı. Adım adım gidelim.

Redoc kullanımı

API dokümanları için kullanılan başka bir görüntüleme aracıdır.

Detaylar için: https://github.com/Redocly/redoc

ASP.NET ile direkt kullanamıyorsunuz. Swagger, Redoc ile ASP.NET arasında bir köprü olacak. Bu aralarındaki bağlantıyı Swagger çıktısı ile yapacağınız.

Yukarıda dikkat ederseniz Swagger UI sayfasına gitmiştik. Arayüze dikkat ederseniz bir tane “http://localhost/api/swagger/docs/v1” şeklinde url var. Buna giderseniz size JSON döndüğünü görürsünüz.

Redoc’u çalışır hale getirme

  • Kendime bir tane klasör açtım. İsmi “Redoc”. (Bu klasörü GitHub’a atmak için proje klasörünün içine aldık. Siz istediğiniz yere alabilirsiniz.)
  • Klasörün içine script dosyalarını tutmak için “Scripts” adında klasör ile “index.html” dosyası ekledim.
  • Redoc için kullanılacak script dosyasını kendime indirip kullanıyorum. Local path olarak veriyorum.
  • Sonra yukarıda Swagger/v1 ile JSON veren url bilgisini “index.html” sayfasına girdikten sonra Redoc çalışır hale gelecektir.
Henüz boş olan Redoc çıktısı
Redoc index sayfası

Artık Controller ekleyip görüntüleyelim. Ufak sıkıntıların çözüme geçelim.

Dokümanın detaylı oluşturulması

İlk olarak şunu söylemeliyim, burada bulduğum çözümler bir şekilde araştırıp veya kendimin bulduğu yöntemlerdir. Sizin için, aslında bu daha iyi bir yöntem dediğiniz yerler olursa bu yazıya cevap yazmanız beni mutlu eder.

1 — Controller ve modellerin eklenmesi

  • İki tane Controller ekledim. İsimleri “CustomersController” ve “ProductsController”. Bunların içlerinde “Index”, “Get” ve “Edit” methodları var.
  • Modeller ile beraber, bunların kodunu buraya eklemek istemiyorum. Yazı yeterince uzun zaten. GitHub üzerinde son hali olacak. Şuradan bakabilirsiniz: https://github.com/alincak/SwaggerRedoc
Güzel olmaya başladı :)

2 — SwaggerConfig ufak düzeltmeler

EnableSwagger için;

  • “Schemes” içerisine sadece “https” ekledim. “ c.Schemes(new[] { “https” });”
  • Benim yaptığım sistem “BasicAuth” ile çalışmaktaydı. “ c.BasicAuth(“basic”).Description(“Basic HTTP Authentication”);”
  • Enum propertylerin listesini görmek için “ c.DescribeAllEnumsAsStrings();” açık olmalıdır.

EnableSwaggerUi için;

  • Burada bende sadece şurası açık. “ c.DocumentTitle(“My Project— API”);”

3 — [“ISchemaFilter” kullanımı] Değişkenlerin “Gizlenmesi” ve [FromBody] için “nullable” ve “defaultValue”

“Schema” kavramı Swagger’ın listesinde bulunan model objesidir. Burada yaşadığımız sıkıntılar şunlardı;

  • Bazı modellerin içerisinde, API entegrasyonu yapacak kullanıcıların görmesini istemediğiniz değişkenler olabilir. Bunların bir şekilde API dokümanında görünmesin diyebilirsiniz. Ama bunu Swagger ile yapamıyorsunuz. Bunu siz yazacaksınız.

“SwaggerExcludeAttribute” diye bir tane “CustomAttribute” yaptım.

Bunu tanımladığınız değişken “Swagger Schema” içerisinden çıkarılacak. Yukarıda kodda görebilirsiniz.

  • Bir diğer sorun ise, maalesef “Default value” ve “Nullable” konusu. Aslında Swagger UI üzerinde kontrol etmedim. Belki ettim ama hatırlamıyorum. “Default value” Swagger sorunu. “Nullable” ise tamamen Redoc ile Swagger uyuşmazlığı.

Gittim Redoc sayfasına. Size bir tane örnek yapılmış bir çalışma sunuyor. Sayfasını ziyaret ederseniz “Live demo” linkini görürsünüz. Gittim ve “Download” diyerek çıktısını indirdim, inceledim. Benden nasıl istediğini buldum.

Default value için çözüm kolaydı. Direkt “Schema” içinde “@default” alanına yazarsanız çözülüyor. “_schema.@default = _value;”

Nullable konusu biraz zamanımı aldı. Swagger ve Redoc bu konuda uyuşmuyordu. Araştırdım. En son “vendorExtensions” yöntemini buldum. Eğer bir değişken nullable ise “_schema.vendorExtensions.Add(“nullable”, true);” diye ekliyorsunuz.

Biraz daha güzelleşti :)

4 — [“IOperationFilter“ kullanımı] “ContentType”, “SchemaOneOf” ve [FromUri] için “Default value” ve “Nullable”

  • “ContentType” bizim için sadece “application/json” olmalıydı. Burada Request ve Response için listede sadece bunun olması gerekiyor. “InitSetContentTypeJson” bu işi yapmaktadır.
  • Önceki konuda anlatmıştım. “Default value” ve “Nullable” sorunu yine burada da var. Yalnız, burada fark birinin “FromBody”, diğerinin “FromUri” olması.
  • Bunların dışında güzel bir özellik olan “oneOf” işlemini burada yapıyoruz. Bu işi “InitSchemaOneOf” ile yaptık. “oneOf” bir response için HttpStatus 200(OK) olup farklı modeller dönme ihtimali var ise kullanıyoruz. Örneğin, bir işlemin başarısız olduğu durumda farklı bir model dönüyorken, başarılı olduğu durumda başka bir model dönebilirsiniz. Bu “oneOf” işlemini direkt methodlar üzerinden yapamıyorsunuz.

Dikkat: Burada dikkat etmemiz gereken bir konu var.

“CustomerController->Get” methoduna dikkat ederseniz “CustomerGetResponseVo” modeli var. Bunun içerisine “oneOf” ile göstereceğimiz iki modeli ekledim.

Neden? Çünkü, bunları “oneOf” ile vermeniz için Swagger kendi Schema listesine alması gerekiyor. Ondan sonra “ApplyOperationFilter” ile sen bunları dönebilirsin diyoruz.

Güzelleşmeye devam :)

5 — [IDocumentFilter kullanımı] genel bilgiler, iletişim bilgileri, logo, güvenlik, etiket gruplama ve etiket açıklamaları

  • Genel bilgiler, buna hashtag diyorum. Paylaşımdan göreceksiniz. Sola dayatmanız gerekmektedir. “GetInfoDescription” bu görevi yapmaktadır.
  • İletişim bilgileri, burada destek iletişim bilgileri var. Bunun yanında logo burada eklenir. Logo’yu ASP.NET MVC için Swagger desteklemiyor. Redoc için biraz zamanımı aldı. Logo’yu yapmak için Redoc script dosyasını incelemek zorunda kaldım. “GetInfo” bu görevi yapmaktadır.
  • Etiket gruplama ve açıklamaları, bu güzel bir özellik. Controller’lar arasında gruplama yapıyorsunuz. İlgili alanları bir araya topluyorsunuz. Bunların kendilerine ait açıklama kısımları olmaktadır. “GetTagGroups” ve “GetTagsDescription” bu görevi yapmaktadır.
  • Güvenlik tanımlamaları, “GetSecurityDefinitions” bu işi yapmaktadır.

6— IncludeXmlComments kullanımı

Bu yöntem ile bütün methodlara ve değişkenlere açıklama ekleyebilirsin.

Adım adım;

  • Projeye sağ tıklayıp “Properties” diyip “Build” sekmesine gelin.
  • “Output” altında “XML documentation file” alanını seçili hale getirin.
  • SwaggerConfig dosyasında “IncludeXmlComments” alanını açıp şunu ekleyin.

c.IncludeXmlComments(string.Format(@”{0}\bin\SwaggerDoc.xml”, AppDomain.CurrentDomain.BaseDirectory));

  • Bu özellik aktif hale geldiğinde, bütün alanlar için warning uyarısı gelicek. Yani hepsi için açıklama girmenizi isteyecek. Eğer görünmesini istiyorsanız bırakabilirsiniz.
  • Bu uyarıları kaldırmak istiyorsanız. Yine “Properties->Build” ekranından “Suppress warnings” alanına “1591” yazın ve save edin.

7 — SwaggerResponse kullanımı

SwaggerResponse” ile farklı HttpStatus dönüşlerinin bildirimini yapabilirsin.

Yukarıda verdiğim kod ile bu method “NotFound” dönebilir. Eğer dönerse sana dönecek model ise bu diye bildirim yapıyorum. Eğer Model vermezseniz modelsiz sadece 404 yazar.

HttpStatus ve Route kullanımı

  • Her eklediğiniz method için mutlaka belirtin [HttpGet], [HttpPost] gibi.
  • Route ile url değişikliği yapabilirsiniz. API projelerinde versiyon geçişlerinde versiyon değişikliği olabilir.

Örn: [Route(“v1/Customers/Index”)]

Burada dikkat etmeniz gereken ve uzun süre sonra bulduğumuz bir sıkıntı olabilir. HttpStatus ve Route işlemlerinin doğru çalışması için using bloğunda “using System.Web.Http;” olduğuna emin olun.

Biz “using System.Web.Mvc;” olarak unutmuşuz. Burada da HttpStatus ve Route olduğu için sıkıntının Swagger ile alakalı olduğunu düşünmüştük. :)

KA

--

--