API Tasarımı & HTTP Protokolü 3 dk okuma 10 okunma

Content Negotiation: JSON, XML ve Diğer Medya Türleri

Content Negotiation, istemci ile sunucunun en uygun veri formatı (medya tipi) üzerinde anlaşmasını sağlayan HTTP mekanizmasıdır. İstemci Accept başlığıyla tercihini bildirir, sunucu Content-Type ile yanıt formatını açıklar. ASP.NET Core'da JSON varsayılandır; XML ve özel formatlar (CSV, Protobuf) formatter eklenerek desteklenir. Doğru yapılandırıldığında API hem esnek hem performanslı olur.

Content Negotiation: JSON, XML ve Diğer Medya Türleri

Content Negotiation: JSON, XML ve Diğer Medya Türleri

Aynı API, farklı istemciler tarafından farklı formatlarda tüketilmek istenebilir: web uygulamaları JSON, eski kurumsal sistemler XML, yüksek performanslı mikroservisler Protobuf tercih edebilir. Content Negotiation (İçerik Pazarlığı), HTTP'nin bu ihtiyacı karşılayan mekanizmasıdır. İstemci ve sunucu, istek/yanıt formatı üzerinde standart başlıklar aracılığıyla anlaşır.


1. Temel Mekanizma: Accept ve Content-Type

Content Negotiation iki HTTP başlığı üzerinden yürür:

Accept (İstemci → Sunucu): İstemci, hangi medya tiplerini kabul ettiğini ve tercih sırasını (q değeri ile) belirtir.

http

Accept: application/json, application/xml;q=0.9, text/plain;q=0.8

Bu örnekte istemci öncelikle JSON, ikinci olarak XML, üçüncü olarak düz metin istemektedir.

Content-Type (Sunucu → İstemci): Sunucu, yanıtın hangi formatta olduğunu bildirir.

http

Content-Type: application/json; charset=utf-8

Ek Başlıklar:

  • Accept-Charset: Karakter kodlaması tercihi (ör. UTF-8).

  • Accept-Encoding: Sıkıştırma tercihi (gzip, br).

  • Accept-Language: Dil tercihi (tr, en).


2. Yaygın Medya Tipleri

Medya Tipi Kullanım Alanı
application/json Modern REST API'ler, web/mobil uygulamalar (varsayılan)
application/xml Kurumsal entegrasyon, eski sistemler, SOAP
application/x-protobuf Yüksek performanslı mikroservis iletişimi
application/x-msgpack JSON'a alternatif, daha küçük binary format
text/csv Veri dışa aktarma, raporlama
application/problem+json RFC 9457 hata yanıtları
application/octet-stream Ham binary veri (dosya indirme)

3. ASP.NET Core'da Content Negotiation

ASP.NET Core, ObjectResult ve [ApiController] ile Content Negotiation'ı otomatik destekler. Varsayılan olarak JSON döner; XML ve özel formatlar için formatter eklenmesi gerekir.

A. XML Desteği Ekleme

csharp

// Program.cs
builder.Services.AddControllers()
    .AddXmlSerializerFormatters(); // veya AddXmlDataContractSerializerFormatters()

Bu eklendikten sonra, Accept: application/xml gönderen istemciye otomatik olarak XML döner.

B. Özel Formatter: CSV Örneği

csharp

public class CsvOutputFormatter : TextOutputFormatter
{
    public CsvOutputFormatter()
    {
        SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("text/csv"));
        SupportedEncodings.Add(Encoding.UTF8);
    }

    protected override bool CanWriteType(Type type)
        => typeof(IEnumerable<>).IsAssignableFrom(type) || type.IsArray;

    public override async Task WriteResponseBodyAsync(
        OutputFormatterWriteContext context, Encoding selectedEncoding)
    {
        var response = context.HttpContext.Response;
        var items = (IEnumerable<object>)context.Object;

        await response.WriteAsync("Id,Name,Price\n");
        foreach (var item in items)
        {
            var props = item.GetType().GetProperties();
            var values = props.Select(p => p.GetValue(item)?.ToString() ?? "");
            await response.WriteAsync(string.Join(",", values) + "\n");
        }
    }
}

// Kayıt
builder.Services.AddControllers(options =>
{
    options.OutputFormatters.Add(new CsvOutputFormatter());
});

Artık Accept: text/csv gönderen istemci, veriyi CSV formatında alır.


4. Format Zorlama: Accept vs. Query Parametresi

Bazen istemcinin formatı URL üzerinden belirtmesi istenir. İki yaklaşım vardır:

Yaklaşım Örnek Avantaj Dezavantaj
Accept başlığı Accept: application/xml HTTP standardı Tarayıcıda test zor
Query parametresi ?format=xml Kolay test, görünür Önbellek karmaşası, REST dışı

ASP.NET Core'da [FormatFilter] attribute'ü ile query parametresinden format okunabilir:

csharp

[HttpGet("{id}")]
[FormatFilter]
public IActionResult GetProduct(int id, [FromQuery] string format)
{
    var product = _service.Get(id);
    return Ok(product); // ?format=xml → XML formatter
}

Öneri: Üretim API'lerinde Accept başlığını tercih edin; query parametresini yalnızca test/debug için kullanın.


5. Ne Zaman Hangi Format?

Senaryo Öneri
Web/mobil uygulamalar application/json (varsayılan)
Kurumsal SOAP/XML entegrasyonu application/xml
Yüksek performanslı iç mikroservisler application/x-protobuf veya gRPC
Veri dışa aktarma (Excel, muhasebe) text/csv
Hata yanıtları application/problem+json

Not: Çoğu API için JSON yeterlidir. XML ve diğer formatları yalnızca gerçek bir ihtiyaç varsa ekleyin; her ek format, test ve bakım yükünü artırır.


6. En İyi Pratikler

Pratik Açıklama
JSON'u varsayılan yapın İstemci Accept göndermezse JSON dönün.
Vary: Accept başlığını ekleyin CDN ve proxy'lerin farklı formatları ayrı önbelleklemesini sağlar.
Desteklenen formatları dokümante edin OpenAPI dokümanında her endpoint için desteklenen medya tiplerini belirtin.
Bilinmeyen formatları reddedin 406 Not Acceptable ile geçersiz Accept başlığını yanıtlayın.
Charset'i belirtin Content-Type: application/json; charset=utf-8

Sonuç

Content Negotiation, bir API'nin farklı istemci ihtiyaçlarına tek bir arayüz üzerinden cevap vermesini sağlayan esnek ve standart bir mekanizmadır. JSON, modern API'lerin varsayılan formatıdır; XML ve özel formatlar yalnızca gerçek bir ihtiyaç olduğunda eklenmelidir. ASP.NET Core, Accept başlığı ve ObjectResult ile bu süreci otomatik yönetir; özel formatter'lar ile CSV, Protobuf gibi formatlar da desteklenebilir. Doğru yapılandırıldığında, API'niz hem esnek hem de performanslı olur. Unutmayın: Her ek format, bir esneklik kadar da bakım yüküdür; ihtiyaç kadarını desteklemek, en sağlıklı yaklaşımdır.

Tüm yazılar Soru ya da yorumun mu var? Yaz