NetTopologySuite Bellek Sızıntısı – Swashbuckle (Swagger)

Swashbuckle ve ApiExplorer ile Karmaşık Parametreler: Bellek Sorunları ve Çözümü

Swashbuckle.AspNetCore ve ApiExplorer ile ilgili yaşanan bellek sorunları, özellikle karmaşık türlerin sorgu parametresi olarak kullanıldığı durumlarda sıklıkla karşımıza çıkmaktadır. Bu durum, özellikle NetTopologySuite.Geometries türleri (Geometry, Polygon, Point) gibi karmaşık veri türlerinin sorgu parametresi olarak kullanıldığı API’lerde daha belirgin hale gelir. Bu türler, ApiExplorer tarafından işlenirken, nesne grafiklerinin her bir özelliği tek tek sorgu parametresi olarak ayrılmakta ve bu da bellekte aşırı kullanım ve Swagger UI’nin düzgün çalışmaması gibi sorunlara yol açmaktadır.

Sorunun Temeli

ASP.NET Core, yerleşik meta veri bileşeni olan ApiExplorer‘ı kullanarak, API’nin parametrelerini otomatik olarak keşfeder ve bunları dökümante eder. Bu süreç, özellikle karmaşık türlerin (örneğin, Point gibi türlerin) sorgu parametresi olarak kullanıldığı durumlarda büyük bellek sorunlarına yol açabilir. Çünkü ApiExplorer, nesne grafiğindeki her özellik için ayrı bir parametre oluşturur. Bu, API’ye karmaşık türlerin parametre olarak gönderilmesiyle, çok büyük bir parametre kümesinin ortaya çıkmasına neden olabilir.

Örneğin, aşağıdaki gibi bir QueryParams sınıfınız varsa:

public class QueryParams
{
    public string Foo { get; set; }
    public string Bar { get; set; }
}

Bu durumda, ApiExplorer, QueryParams.Foo ve QueryParams.Bar adında iki ayrı sorgu parametresi oluşturacaktır. Ancak, NetTopologySuite.Geometries.Point gibi karmaşık bir tür kullanıldığında, her bir alt özellik bir parametre olarak ayrılacak ve çok büyük bir parametre seti ortaya çıkacaktır. Bu da bellekte büyük miktarda yer kaplayacak ve Swagger UI’nin düzgün bir şekilde yüklenmemesine veya uygulamanın bellek sınırlarını aşarak çökmesine neden olabilir.

Sorunun Çözümü: TypeConverter Kullanımı

Bu sorunun çözümü için, karmaşık türlerin sorgu parametresi olarak işlenmesini engellemek ve bu türleri dize (string) türüne dönüştürmek gerekmektedir. Bu, TypeConverter kullanılarak yapılabilir. Ancak, bu çözüm, ApiExplorer‘ın sadece özel bir bağlayıcıyı (custom binder) desteklemesi nedeniyle, doğrudan Swagger ile yapılandırılamaz. Bunun yerine, TypeConverter kullanarak karmaşık türlerin sorgu parametresi olarak işlenmesini dize olarak yapabiliriz.

Çözüm Adımları

  1. TypeConverter Kaydı
    İlk adım olarak, Point türü için özel bir TypeConverter sınıfı oluşturulmalıdır. Bu sınıf, gelen dize değerini doğru şekilde dönüştürecektir. Bu dönüştürme işleminden sonra, Point türü Swagger’a bir dize olarak kaydedilecektir.
  2. Swagger Konfigürasyonu
    Daha sonra, SwaggerGen konfigürasyonunda, Point türü için bir özel eşleme (mapping) yapılmalıdır. Bu eşleme, Point türünü bir dize olarak tanımlar.

Adım Adım Uygulama

1. TypeConverter Oluşturma

Öncelikle, Point türü için bir TypeConverter sınıfı oluşturulmalıdır. Bu sınıf, Point nesnesini bir dizeden dönüştürmeye yönelik bir işlevi yerine getirecektir.

public class PointTypeConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) =>
        sourceType == typeof(string);

    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) =>
        // Burada value.ToString() kullanarak Point nesnesini dizeden dönüştürmelisiniz
        new Point(Convert.ToDouble(value.ToString().Split(',')[0]), Convert.ToDouble(value.ToString().Split(',')[1]));
}

Bu sınıf, gelen dizeyi Point türüne dönüştürür.

Tabii, aşağıda belirttiğiniz durumu ve çözüm önerisini içeren bir makale hazırladım. Bu makale, Swagger ile ilgili bellek sorunları ve karmaşık parametreler nedeniyle yaşanan problemleri ele alacak ve çözümü için önerilen yöntemleri açıklayacaktır.

Bu sınıf, gelen dizeyi Point türüne dönüştürür.

2. TypeConverter Kaydının Yapılması

Daha sonra, Startup.cs dosyasında, TypeConverter‘ın doğru şekilde kaydedilmesi gerekir. Aşağıdaki kodu, ConfigureServices metodunda kullanarak bunu sağlayabilirsiniz:


Bu işlem, Point türünün Swagger’da bir dize olarak gösterilmesini sağlar.

public void ConfigureServices(IServiceCollection services)
{
 // NetTopologySuite.Point türü için TypeConverter kaydını yapıyoruz
 TypeDescriptor.AddAttributes(typeof(Point), new TypeConverterAttribute(typeof(PointTypeConverter)));

 services.AddSwaggerGen(c =>
 {
 // Swagger'da Point türünü bir dize (string) olarak tanımlıyoruz
 c.MapType<Point>(() => new OpenApiSchema { Type = "string" });
 });
}

Hızlı Çözüm

Swagger’ı devre dışı brakın. 🙂

Sonuç

Bu adımları uyguladıktan sonra, karmaşık türler (örneğin, Point) sorgu parametresi olarak kabul edilecek ve Swagger UI’de düzgün bir şekilde görüntülenecektir. Bellek sorunları ve Swagger’ın yüklenmemesi gibi problemler, bu çözümle ortadan kaldırılacaktır. Ayrıca, API’niz karmaşık türlerle çalışırken, bu türlerin doğru şekilde dize olarak işlenmesi, ApiExplorer‘ın meta verilerini daha verimli kullanmanıza yardımcı olacaktır.

Yorum Yap:

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

Site Footer

Sliding Sidebar