Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
API Tasarımı Neden Mimari Bir Karardır? Contract, Tüketici, REST'in Gerçekte Ne Olduğu ve Style Guide'lar
API tasarımı mimari bir karardır, çünkü contract tüketicinin gözlemleyebildiği her şeydir ve onu değiştirmek tüketicileri de değiştirmeyi gerektirir. Bookstore'un 200 içinde hata dönen eski RPC endpoint'inden yola çıkıp Fielding'in REST kısıtlarını, Richardson Maturity Model'i, HATEOAS'ın gerçekten işe yaradığı yerleri, Azure, Google AIP ve Zalando rehberlerini karşılaştırıyor ve kendi style guide'ımızı ADR olarak yazıp Spectral ile zorluyoruz.
Resource Modelleme ve URL Tasarımı: Collection, Sub-resource, Naming, Custom Action'lar ve Fiil Gerektiğinde
İyi bir URL tasarımında resource'lar tablolardan değil domain'in dilinden çıkar, her resource'un tek kanonik adresi olur ve fiil gereken iş ya custom method ya da kendi yaşam döngüsü olan yeni bir resource olur. Bookstore'un kurumsal sipariş adreslerini, singleton sepeti, ISBN, UUID v7 ve slug kimlik seçimlerini, POST /orders/{id}:cancel ile iade resource'unu gerçek HTTP yanıtları ve Spectral kurallarıyla tasarlıyoruz.
HTTP Method ve Status Code Semantiği: Safe, Idempotent, PUT mu PATCH mı, 200/201/202/204/409/412/422 Kararları
Method ve status code seçimi, RFC 9110'daki safe ve idempotent tanımlarına ve ekipçe bir kez yazılmış bir karar kuralına dayanmalı: 400 bozuk istek, 422 iş kuralının reddettiği geçerli istek, 409 resource'un durumuyla çakışma, 412 If-Match uyuşmazlığı. Bookstore'da POST ile 201 ve Location'ı, PUT ile oluşturmayı, JSON Merge Patch ile 415 ve Accept-Patch'i, 401, 403, 404 ve 405 ayrımını gerçek yanıtlarla görüyoruz.
Hata Contract'ı: RFC 9457 Problem Details, Hata Kodu Kataloğu, Validation Hataları ve Yerelleştirme
İyi bir hata contract'ı, RFC 9457 Problem Details üzerine kurulur ve makine için sabit alanları (type, extension'lar, errors anahtarları) insan için yerelleşen alanlardan (title, detail) ayırır. Bookstore'da hata türlerini bir kataloğa bağlıyor, validation anahtarlarını JSON yollarına ve kural kodlarına çeviriyor, Accept-Language ile Türkçe hata dönüyor, ortama göre değişen 500'ü ve stack trace sızıntısını düzeltiyor ve Angular'da tek bir interceptor yazıyoruz.
Koleksiyon Endpoint'leri: Pagination, Filtering, Sorting, Field Selection ve Arama Sözleşmesi
Bir liste endpoint'inin contract'ı item şemasından ibaret değildir; sayfa boyutu kuralları, opaque ve sorguya bağlı bir sayfa token'ı, yazılı bir sıralama ve tie-breaker, bilinmeyen parametreye verilen hata da contract'tır. Bookstore'da çözülebilen Base64 token'ı şifreli keyset token'ıyla, sessizce yok sayılan filtreyi 400 ile değiştiriyor, Link header'ını, sparse fieldset'i, AIP-160 filtre dilini ve RFC 10008 QUERY method'unu gerçek yanıtlarla tartışıyoruz.
Değişikliğe Dayanıklı API: Breaking Change Kuralları, Versioning Stratejileri, Deprecation (RFC 9745) ve Sunset (RFC 8594)
Bir API'yi kırmadan değiştirmenin yolu, additive değişiklikleri sürümsüz yayımlamak, response enum'larını baştan açık tanımlamak ve gerçek breaking change'i yeni bir sürümle, Deprecation ve Sunset header'larıyla duyurarak çıkarmaktır. Bookstore'da yeni bir sipariş durumunun strict bir .NET istemcisini nasıl kırdığını, author alanını authors ile değiştirirken tarihli api-version'ı, RFC 9745 ve RFC 8594 header'larını ve deprecated sürümün kullanım log'unu gerçek yanıtlarla görüyoruz.
Concurrency, Idempotency ve Uzun Süren İşlemler: ETag/If-Match, Idempotency-Key, 202 Accepted ve Status Monitor
Eşzamanlı ve tekrarlanan yazmalara karşı contract'ta üç araç var: var olan resource'u değiştiren her istekte zorunlu If-Match (yoksa 428), oluşturan POST'larda Idempotency-Key ve saniyeler süren işler için 202 Accepted ile bir status monitor. Bookstore'da sessizce kaybolan bir fiyat indirimini, aynı anahtarla tekrar gönderilen siparişi, 409 ve 422 durumlarını ve fatura PDF'inin başarılı, başarısız ve iptal edilen LRO akışlarını gerçek yanıtlarla görüyoruz.
Bulk, Batch ve Asenkron API'ler: Toplu İşlem, Kısmi Başarı, Webhook mi Polling mi ve Rate Limit Contract'ı
Toplu bir API'nin contract'ı boyut sınırını, hangi hatanın bütün isteği hangisinin tek satırı reddettiğini, kısmi başarının nasıl raporlandığını, sonucun nasıl bildirildiğini ve kotayı açıkça yazar. Bookstore'da okulların toplu siparişini satır bazlı bir raporla 201 olarak, allOrNothing ile 422 olarak, Prefer: respond-async ile LRO olarak tasarlıyor, webhook'u contract'a ekliyor ve RateLimit header taslağıyla 429'u gerçek yanıtlarla görüyoruz.
API-First ve OpenAPI 3.2 ile Contract: Design-First Akış, Spectral ile Lint, Breaking Change Diff ve Mock Server
Design-first akışta OpenAPI contract'ı bir build girdisidir: her PR'da style guide lint edilir, hedef branch'e göre breaking change aranır, üretilen client'ın güncelliği ve koddan üretilen dokümanla drift kontrol edilir. Bookstore'da bir Spectral kuralının neden hiç hata vermediğini, oasdiff'in silinen parametreyi neden yalnız uyarı saydığını, eski RPC endpoint'ini bulan drift kontrolünü, Prism mock'unu ve openapi-typescript ile Angular tiplerini gerçek çıktılarla görüyoruz.
API Review ve Governance: Review Checklist'i, Tasarım Kararlarını Belgelemek ve Bookstore Public API'sinin Uçtan Uca Tasarımı
API review, kod yazılmadan önce contract PR'ında, yazılı bir checklist'le ve danışma niteliğinde yapılmalı; araçların kontrol edebildiği her şey araca bırakılır, insan anlam, tüketici ve güvenliğe bakar. Bookstore'da bir partner taslağını lint ve review ile inceliyor, review bulgusunu yeni bir lint kuralına çeviriyor, ADR'ları ve API envanterini topluyor, satın alma onayı API'sini gerçek yanıtlarla uçtan uca tasarlıyor ve seriyi kapatıyoruz.