İlkay İlknur

.NET Core'da JSON API'ları

Temmuz 02, 2020

.NET ekosistemi içerisinde JSON işlemleri denince akla gelen ilk kütüphane Newtonsoft.Json kütüphanesi. Microsoft yıllar boyunca .NET içerisinde yüksek performanslı ve gömülü bir çözüm geliştirmek yerine bu kütüphaneyi hem kullandı hem de developerlara tavsiye etti. Ancak .NET Core 3.0 ile bu hikaye biraz değişti. .NET Core 3.0 ile beraber Microsoft JSON operasyonları için yeni API'lar implemente etti ve artık ASP.NET Core içerisinde de bu API'ları kullanarak Newtonsoft.Json kütüphanesine olan bağımlılıktan kurtuldu. Bu kütüphane özellikle son zamanlarda gelen Span, Memory gibi tipleri alt tarafta etkin bir şekilde kullanarak oldukça performanslı ve daha az memory kullanan bir altyapıyı bizlere sunuyor. Şimdi gelin bu yeni API'lara biraz yakından bakalım.

Yeni API'ların bulunduğu namespaceler şunlar.

  • System.Text.Json
  • System.Text.Json.Serialization

En basit anlamda serialize/deserialize işlemleri için JsonSerializer tipi içerisindeki static Serialize/Deserialize metotlarını kullanabiliriz.

var person = new Person()
{
    Id = 1,
    Name = "ilkay",
    Surname = "ilknur"
};
 
var json = JsonSerializer.Serialize(person);
var obj = JsonSerializer.Deserialize<Person>(json);

Serialize/deserialize işlemleri sırasında default olan bazı değerleri değiştirmek istediğimizde JsonSerializerOptions nesnesi yaratıp ilgili metotlara parametre olarak geçebiliriz.

JsonSerializerOptions options = new JsonSerializerOptions()
{
    WriteIndented = true,
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var json = JsonSerializer.Serialize(person,options);
var obj = JsonSerializer.Deserialize<Person>(json,options);

JsonSerializer tipi aynı zamanda stream bazlı serialize/deserialize işlemleri için asenkron metotlar bulundurmakta.

var stream = File.OpenRead("c:\\person.json");
var person = await JsonSerializer.DeserializeAsync<Person>(stream);
            
await JsonSerializer.SerializeAsync(stream, person);

Yeni JSON API'larındaki dikkat çeken implementasyonlardan biri de Utf-8 byte array'e doğrudan çevirme opsiyonu.

byte[] data = JsonSerializer.SerializeToUtf8Bytes(person);

JSON serialize/deserialize operasyonları esnasında belli propertylerin ignore edilmesi veya farklı isimle temsil edilmesi gibi işlemleri aynı newtonsoft.json kütüphanesinde olduğu gibi attributeler aracılığıyla yapabiliyoruz.

class Person
{
    [JsonIgnore]
    public int Id { getset; }
    public string Name { getset; }
    public string Surname { getset; }
    [JsonPropertyName("ttl")]
    public int TimeToLive { getset; }
}

Enumları string olarak serialize/deserialize etmek istersek built-in gelen JsonStringEnumConverter converterını kullanabiliriz.

var person = new Person()
{
    Id = 1,
    Name = "ilkay",
    Surname = "ilknur",
    Role = Roles.Admin
};
var serializerOptions = new JsonSerializerOptions();
serializerOptions.Converters.Add(new JsonStringEnumConverter());
var json = JsonSerializer.Serialize(person, serializerOptions);

ASP.NET Core İçerisinde Kullanım

ASP.NET Core 3.0 ile beraber artık dışarıdan özellikle belirtmediyseniz alt katmanlarda bahsettiğimiz yeni Json API'ları kullanılıyor. Bu nedenle serialize/deserialize operasyonlarında değiştirmek istediğimiz detaylar olduğunda şu şekilde konfigüre edebiliriz.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddJsonOptions(options =>
            {
                options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
            });
}

API'larınızda eğer yeni gelen System.Text.Json altyapısına geçmeye hazır değilseniz Newtonsoft.Json kütüphanesini kullanma imkanınız da mevcut. Bunun için öncelikle Microsoft.AspNetCore.Mvc.NewtonsoftJson paketini yükleyip sonrasında aşağıdaki gibi konfigüre etmeniz gerekiyor.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers()
            .AddNewtonsoftJson();
}

Dikkat Çeken Diğer Özellikler

Yeni Json API'larında dikkatimi çeken ancak bu yazıda bahsetmeyeceğim özelliklerden ikisi Utf8JsonWriter ve Utf8JsonReader yapısı. Özellikle belirli senaryolarda performanslı ve az memory kullanarak belirli işlemleri gerçekleştirmek mümkün. Eğer sizin de ilginizi çektiyse linke tıklayıp inceleyebilirsiniz.

Gözümüz Kapalı Bu Kütüphaneye Geçmeli Miyiz?

Gelelim en kritik soruya 😃 Bahsettiğimiz JSON API'ları takdir edersiniz ki Newtonsoft.Json kütüphanesine göre oldukça yeni. Newtonsoft.Json kütüphanesine baktığımızda oldukça eski ve olgun bir kütüphane olduğunu görüyoruz. Yıllar boyunca pek çok özelliği implemente etti bu nedenle aradığımız bazı özellikler haliyle bu yeni API'larda henüz olmayabilir. Microsoft bunun için çok güzel bir döküman hazırlayıp hangi özellikler var, yok olmayan özelliklerle ilgili nasıl workaround yapabiliriz gibi konulara cevap veriyor. Bu dökümana göre bakıp ilerlemekte fayda var. Duruma göre değişmekle beraber doğrudan kütüphane güncellemesiyle tamamlanacak bir geçiş olmayacağını söyleyebiliriz. Ancak yeni geliştirdiğimiz uygulamalarda artık doğrudan Newtonsoft.Json kütüphanesi yerine yeni API'ları kullanmakta fayda var diye düşünüyorum. .NET 5 ile beraber JSON API'larının biraz daha genişlemesiyle ve olgunlaşmasıyla beraber de geçişlerin artacağını da tahmin etmek zor olmayacaktır.

Bir sonraki yazıda görüşmek üzere,