8 dk

API Evrimi ve Yapay Zeka Back-end'lerinde Geriye Dönük Uyumluluk

API'lerin nasıl güvenli evrildiğini öğrenin: sürümlendirme, uyumlu değişiklikler, migrasyon adımları, kaldırma politikası ve istemcileri bozmayan testler.

API Evrimi ve Yapay Zeka Back-end'lerinde Geriye Dönük Uyumluluk

Yapay zeka tarafından oluşturulan back-end'ler için API evrimi ne demektir

API evrimi, bir API gerçek istemciler tarafından kullanıldıktan sonra yapılan değişikliklerin sürekli sürecidir. Bu, alan eklemek, doğrulama kurallarını ayarlamak, performansı iyileştirmek veya yeni uç noktalar tanıtmak anlamına gelebilir. Gerçek kullanıcılar üretimde olduğunda önem kazanır; çünkü “küçük” bir değişiklik bir mobil uygulama sürümünü, bir entegrasyon betiğini veya bir ortak iş akışını bozabilir.

Basitçe açıklamak gerekirse: geriye dönük uyumluluk

Bir değişiklik, mevcut istemciler herhangi bir güncelleme yapmadan çalışmaya devam ediyorsa geriye dönük uyumlu sayılır.

Örneğin, API'niz şu yanıtı döndürüyor olsun:

{ "id": "123", "status": "processing" }

Yeni, isteğe bağlı bir alan eklemek genellikle geriye dönük uyumludur:

{ "id": "123", "status": "processing", "estimatedSeconds": 12 }

Bilinmeyen alanları görmezden gelen eski istemciler çalışmaya devam eder. Buna karşılık, statusstate olarak yeniden adlandırmak, bir alanın tipini değiştirmek (string → number) veya isteğe bağlı bir alanı zorunlu yapmak yaygın kırıcı değişikliklerdir.

Burada “AI tarafından oluşturulan backend” ne demek

AI tarafından oluşturulan bir backend sadece bir kod parçası değildir. Pratikte şunları içerir:

  • Üretilmiş API kodu (handler'lar, controller'lar, serializer'lar)
  • Konfigürasyon (yönlendirme, auth kuralları, rate limitler)
  • Altyapı bağlantıları (migrasyonlar, dağıtım şablonları, ortam ayarları)

AI, sistemi hızlıca yeniden üretebildiği için API zaman içinde "sürüklenebilir"; bu yüzden değişiklikleri kasıtlı olarak yönetmezseniz sözleşme disiplinine ihtiyaç artar.

Bu, sohbetten tam uygulamalar ürettiğinizde daha da önem kazanır. Örneğin Koder.ai gibi bir platform, basit bir sohbette React (web), Go + PostgreSQL (backend) ve Flutter (mobil) kullanarak web, sunucu ve mobil uygulamalar oluşturabilir. Bu hız faydalıdır, ancak yeniden üretilen sürümlerin istemcilerin dayandığı davranışı kazara değiştirmemesi için sözleşme disiplini ve otomatik diff/testler daha önemlidir.

Neyi otomatikleştirirsiniz, neyi insan incelemesi gerekir

AI pek çok şeyi otomatikleştirebilir: OpenAPI spec'leri üretmek, boilerplate kodu güncellemek, güvenli varsayılanlar önermek ve hatta migrasyon adımlarını taslak hâline getirmek. Ancak kullanıcı sözleşmelerini etkileyen kararlar—hangi değişikliklere izin verileceği, hangi alanların kararlı olduğu, uç durumlar ve iş kuralları—için insan incelemesi hâlâ gereklidir. Amaç hız ve öngörülebilir davranıştır; sürpriz pahasına hız değil.

Neden geriye dönük uyumluluk öncelikli olmalı

APİ'lerin nadiren tek bir "istemcisi" olur. Küçük bir üründe bile aynı uç noktalara bağımlı birden fazla tüketici olabilir:

  • Sürekli dağıtılan bir web uygulaması
  • Uygulama mağazalarında daha yavaş güncellenen bir mobil uygulama
  • Başka ekipler veya şirketler tarafından yönetilen ortak entegrasyonlar
  • Dahili servisler ve otomasyonlar (faturalama, analiz, destek araçları)

Bir API bozulduğunda maliyet sadece geliştirici zamanı değildir. Mobil kullanıcılar eski sürümlerde haftalarca takılı kalabilir; bu da uzun kuyruklu hatalar ve destek biletleri doğurur. Ortaklar kesinti yaşayabilir, veri kaçırabilir veya kritik iş akışları durabilir—sözleşmesel veya itibara dair sonuçlar doğabilir. Dahili servisler sessizce başarısız olabilir ve temizlenmesi zor yığınlar oluşabilir (örneğin eksik olaylar veya tamamlanmamış kayıtlar).

AI tarafından oluşturulan backend'ler farklı bir zorluk getirir: kod hızlı ve sık değişebilir, bazen büyük diff'lerle, çünkü üretim çalışma kodu üretmeye odaklıdır—zaman içinde davranışı korumaya değil. Bu hız değerlidir ama aynı zamanda adını değiştirilmiş alanlar, farklı varsayılanlar, daha sıkı doğrulama veya yeni auth gereksinimleri gibi kazara kırıcı değişiklikler riskini artırır.

Bu yüzden geriye dönük uyumluluk kasıtlı bir ürün kararı olmalıdır, bir alışkanlık değil. Pratik yaklaşım, API'yi bir ürün arayüzü gibi ele alan tahmin edilebilir bir değişiklik süreci tanımlamaktır: yetenekler ekleyebilirsiniz, ancak mevcut istemcileri şaşırtmazsınız.

Yararlı bir zihni model, API sözleşmesini (ör. bir OpenAPI spec) istemcilerin güvenebileceği "gerçeklik kaynağı" olarak ele almaktır. Üretim sonra bir uygulama detayıdır: backend'i yeniden üretebilirsiniz, ama sözleşme—ve verdiği vaatler—bilinçli bir sürümleme ve iletişim olmadan değişmez.

API sözleşmesi: gerçeklik kaynağı

AI sistemi backend kodunu hızlıca üretebilir veya değiştirebilirken, tek güvenilir çapa API sözleşmesidir: istemcilerin ne çağırabileceğini, ne göndermek zorunda olduklarını ve ne bekleyebileceklerini yazılı olarak tanımlayan belge.

Pratikte “sözleşme” ne anlama gelir

Bir sözleşme, makine tarafından okunabilir bir spec olabilir:

  • REST uç noktaları için OpenAPI (yollar, parametreler, auth, yanıt şekilleri)
  • İstek/yanıt yüklerini doğrulamak için JSON Schema (çoğunlukla OpenAPI içinde gömülü)
  • Tipler, sorgular, mutasyonlar ve deprecations için GraphQL schema

Bu sözleşme dış tüketicilere verdiğiniz taahhüttür—uygulamanın arkasındaki implementasyon değişse bile.

Contract-first vs. code-first (ve jeneratörlerin yeri)

Contract-first iş akışında, OpenAPI/GraphQL şemasını önce tasarlarsınız, sonra sunucu stub'ları üretip mantığı doldurursunuz. Bu genellikle uyumluluk açısından daha güvenlidir çünkü değişiklikler kasıtlı ve incelenebilir.

Code-first iş akışında, sözleşme kod anotasyonlarından veya çalışma zamanından türetilir. AI tarafından üretilen backend'ler genellikle varsayılan olarak code-first eğilimindedir; bu sorun değil—üretilen sözleşme bir çıktı olarak incelenmeli, göz ardı edilmemelidir.

Pratik bir hibrit: AI'ye kod değişikliği önerme izni verin, ancak aynı zamanda sözleşmeyi güncellemesini/yeniden üretmesini zorunlu kılın ve sözleşme diff'lerini ana değişiklik sinyali olarak kullanın.

Sözleşmeyi versiyon kontrolünde tutun

API spec'lerinizi backend ile aynı repoda saklayın ve pull request üzerinden inceleyin. Basit bir kural: sözleşme değişikliği anlaşılmadan merge yok. Bu, geriye dönük uyumsuz düzenlemeleri üretime gitmeden önce görünür kılar.

Sunucu ve istemcileri aynı kaynaktan üretin

Sapmayı azaltmak için sunucu stub'larını ve istemci SDK'larını aynı sözleşmeden üretin. Sözleşme güncellendiğinde her iki taraf da birlikte güncellensin—böylece AI tarafından üretilen implementasyonun istemcilerin beklemediği davranışları "icat etmesi" zorlaşır.

Uygulamada işe yarayan sürümleme stratejileri

API sürümlendirme gelecekteki her değişikliği tahmin etmekle ilgili değildir—istemcilere backend'i iyileştirirken çalışmaya devam etmeleri için net, kararlı bir yol sağlamakla ilgilidir. Pratikte "en iyi" strateji, tüketicilerinizin hemen anlayabileceği ve ekibinizin tutarlı uygulayabileceği stratejidir.

Yaygın stratejiler (istemci açısından nasıl hissettirdiği)

URL sürümlendirme, sürümü yol içinde koyar: /v1/orders ve /v2/orders. Her istekte görünürdür, hata ayıklaması kolaydır ve caching/yönlendirme ile iyi çalışır.

Header sürümlendirme, URL'leri temiz tutar ve sürümü bir header'a taşır (örneğin Accept: application/vnd.myapi.v2+json). Zarif olabilir ama hata ayıklamada daha az belirgindir ve kopyala-yapıştır örneklerinde atlanabilir.

Query parametre sürümlendirme /orders?version=2 gibi bir yapı kullanır. Basittir, ancak istemciler veya proxy'ler query string'leri değiştirirse karışıklığa yol açabilir ve insanlar sürümleri karıştırmaya daha meyillidir.

Varsayılan öneri

Çoğu ekip için—özellikle istemci anlayışını basit tutmak istiyorsanız—URL sürümlendirmeyi varsayılan yapın. En az sürpriz yaratan yaklaşımdır, belgelemek kolaydır ve hangi sürümün çağrıldığını açıkça gösterir.

AI tarafından oluşturulan backend'lerin yardımcı olabileceği yön

AI ile backend üretirken her sürümü ayrı bir "sözleşme + uygulama" birimi olarak ele alın. Güncellenmiş bir OpenAPI spec'ten yeni bir /v2 iskeleti oluşturup /v1'i olduğu gibi bırakabilirsiniz; iş mantığını mümkün olduğunca paylaşabilirsiniz. Bu, riski azaltır: mevcut istemciler çalışmaya devam eder, yeni istemciler ise kasıtlı olarak v2'yi benimser.

Dokümantasyon ve değişiklik iletişimi

Sürümleme yalnızca dokümanlar güncel kaldığında işe yarar. Sürümlenmiş API dokümanları tutun, sürüme göre örnekleri uyumlu hâlde saklayın ve changelog yayınlayın: ne değişti, ne kullanımdan kalktı ve geçiş notları (tercihen yan yana istek/yanıt örnekleriyle).

Uyumlu vs. kırıcı değişiklikler: pratik kontrol listesi

AI tarafından üretilen backend güncellendiğinde uyumluluğu düşünmenin en güvenli yolu: “Mevcut bir istemci hiçbir değişiklik yapmadan hâlâ çalışacak mı?” Aşağıdaki kontrol listesini kullanarak değişiklikleri yayımlamadan önce sınıflandırın.

Genellikle uyumlu (eklemeci) değişiklikler

Bu değişiklikler genellikle mevcut istemcileri bozmadan yapılır çünkü istemcilerin zaten gönderdiği veya beklediği şeyi geçersiz kılmaz:

  • Yeni isteğe bağlı yanıt alanları (ör. middleName veya metadata). İstemciler tam alan seti beklemiyorsa çalışmaya devam eder.
  • Yeni uç noktalar veya farklı yollarda yeni yöntemler.
  • Yeni isteğe bağlı istek alanları; sunucu bunları yoksayabilir veya varsayılan davranış sergileyebilir.
  • Yanıtlarda genişletilmiş enum'lar (istemciler bilinmeyen değerleri savunmacı şekilde ele almalı).

Genellikle kırıcı (riskli) değişiklikler

Bunları kırıcı olarak değerlendirin:

  • Alanların veya uç noktaların kaldırılması, veya istemcilerin şu anda gönderdiği bir istek alanının desteklenmemesi.
  • Alanların yeniden adlandırılması (anlam aynı olsa bile). Birçok istemci isimle eşleme yapar.
  • Tip değişiklikleri (string → number, object → array, nullable → non-nullable).
  • Davranış değişiklikleri: farklı varsayılanlar, sıralama değişiklikleri, sayfalama semantiği, değiştirilmiş doğrulama kuralları.
  • Kısıtlamaların sıkılaştırılması: önce isteğe bağlı olan bir alanın zorunlu yapılması, maksimum uzunluğun kısaltılması, kabul edilen formatların değiştirilmesi.

Uyumluluk esasınızı "tolerant readers" olarak belirleyin

İstemcileri tolerant reader olmaya teşvik edin: bilinmeyen alanları yoksaymak ve beklenmeyen enum değerlerini zarifçe ele almak. Bu, backend'in alan ekleyerek evrimleşmesine izin verirken istemcileri güncelleme zorunluluğunu azaltır.

AI jeneratörlerinin kuralları nasıl uygulaması gerekir

Bir jeneratör kazara kırıcı değişiklikleri politika ile engelleyebilir:

  • OpenAPI diff'leri alan çıkarma, yeniden adlandırma veya tip değişikliği içeriyorsa merge'i engelleyin, sürüm artışını zorunlu kılın.
  • Her kırıcı değişikliğin önce yeni alan/uç nokta olarak tanıtılmasını ve eski olanlarda deprecate notları eklenmesini isteyin.
  • Yanıt enum eklenmesi veya varsayılanların değişmesi gibi durumlarda uyarı yayınlayın ve uyumluluk incelemesini tetikleyin.

Veritabanı ve şema migrasyonları istemcileri kırmadan

Turn specs into endpoints
Create endpoints, models, and validations, then refine changes without losing control of the contract.

API değişiklikleri istemcilerin gördüğü şeydir: istek/yanıt şekilleri, alan adları, doğrulama kuralları ve hata davranışı. Veritabanı değişiklikleri ise backend'in sakladığı şeydir: tablolar, kolonlar, index'ler, kısıtlar ve veri formatları. İlişkili ama aynı değildirler.

Yaygın hata, bir veritabanı migrasyonunu "sadece dahili" olarak ele almaktır. AI tarafından üretilen backend'lerde API katmanı genellikle şemadan (veya ona sıkı bağlı) üretilir, bu yüzden şema değişikliği sessizce bir API değişikliğine dönüşebilir. Bu, istemcileri etkilemeyi amaçlamadan kırılmalara yol açar.

Güvenli bir migrasyon deseni (expand → migrate → contract)

Her adımda hem eski hem yeni kod yollarının çalışır durumda kalmasını sağlayan çok adımlı yaklaşımı kullanın:

  1. Ekle: mevcut kolonları/tabloları kaldırmadan yeni kolonlar/tablolar ekleyin.
  2. Backfill: yeni alanları mevcut satırlar için doldurun (gerekirse partiler halinde).
  3. Dual-write: backend'in hem eski hem yeni yerlere yazmasını sağlayın.
  4. Okumaları değiştir: okumaları yeni kaynaktan yapmaya başlayın, ama dual-write devam etsin.
  5. Temizle: tüm istemciler güncellendikten ve eski kod kaldırıldıktan sonra eski alanları kaldırın.

Bu desen "büyük patlama" sürümlerinden kaçınır ve geri alma seçenekleri sunar.

Varsayılanlar, null'lar ve "eksik" alanlar

Eski istemciler genellikle bir alanın isteğe bağlı veya kararlı anlamda olduğunu varsayar. Yeni, non-null bir kolon eklerken tercihlerinizi:

  • Sunucu tarafı varsayılan ile davranışı korumak veya
  • Geçici olarak NULL'a izin verip API katmanında bunu açıkça ele almak

arasında yapın.

Dikkat: DB varsayılanı her zaman yardımcı olmayabilir eğer API serializer hala null döndürüyor veya doğrulama kurallarını değiştiriyorsa.

AI tarafından oluşturulan migrasyonlar: yardımcı ama otomatik değil

AI araçları migrasyon scriptleri taslağı oluşturabilir ve backfill önerileri sunabilir, ancak insan doğrulaması gereklidir: kısıtları doğrulayın, performansı (kilitler, index oluşturma) kontrol edin ve eski istemcilerin çalışmaya devam ettiğinden emin olmak için staging verisi üzerinde migrasyonları çalıştırın.

Daha güvenli güncellemeler için feature flag'ler ve kademeli dağıtımlar

Feature flag'ler davranışı uç nokta şeklini değiştirmeden değiştirmenizi sağlar. AI tarafından oluşturulan backend'lerde iç mantık sıkça yeniden üretilebilir veya optimize edilebilir, ancak istemciler kararlı istek/yanıt biçimine güvenmeye devam etmelidir.

Büyük bir anahtar yerine, yeni kod yolunu kapalı gönderebilir, sonra kademeli olarak açabilirsiniz. Bir sorun çıktığında acil yeniden dağıtım yerine flag'i kapatabilirsiniz.

Kademeli dağıtım nasıl işler

Pratik bir rollout planı genellikle üç tekniği birleştirir:

  • Canary release: yeni davranışı önce küçük bir trafik dilimi veya az sayıda tenant için etkinleştirin.
  • Yüzde tabanlı rollout: 1% → 10% → 50% → 100% şeklinde arttırın, hata oranlarını ve istemci etkisini izleyin.
  • Hızlı geri alma planı: hangi metriklerin geri alma tetikleyeceğini önceden tanımlayın (ör. 5xx oranı, doğrulama hataları, destek biletleri) ve flag'i dakikalar içinde geri çevirebilir olun.

API'ler için kilit nokta, yanıtları sabit tutarken iç deneyler yapmaktır. Yeni model, yeni yönlendirme mantığı veya yeni DB sorgu planı gibi implementasyonları değiştirirken sözleşmenin vaat ettiği durum kodlarını, alan adlarını ve hata formatlarını koruyabilirsiniz. Yeni veri eklemeniz gerekirse, istemcilerin görmezden gelebileceği ekleyici alanları tercih edin.

Basit örnek: daha sıkı doğrulamanın kademeli açılması

POST /orders uç noktası şu anda phone'u pek çok formatta kabul ediyorsa ve siz E.164 formatını zorunlu kılmak istiyorsunuz, sıkı doğrulama istemcileri bozabilir.

Daha güvenli yaklaşım:

  1. strict_phone_validation gibi bir flag'in arkasında daha sıkı validator gönderin.
  2. Raporlama modu ile başlayın: isteği kabul edin, ancak hangi isteklerin başarısız olacağını loglayın. Yanıtlar değişmesin.
  3. İç kullanıcılar veya %1 trafik için enforcement'ı canary olarak açın.
  4. Hata artışlarını, istemci tekrarlarını ve düşüşleri izleyerek oranı yükseltin.
  5. Eşikler aşıldığında hemen geri alın.

Bu desen, daha iyi veri kalitesine doğru ilerlerken geriye dönük uyumlu bir API'yi kazara kırmamanızı sağlar.

Kullanımdan kaldırma ve tamamen kapatma: eski sürümleri emekliye ayırma

Safer schema changes
Prototype migrations with expand-migrate-contract steps and keep older clients working during rollouts.

Deprecation, eski API davranışı için "nazik çıkış"tır: onu teşvik etmeyi kesersiniz, istemcilere erken uyarı verirsiniz ve ilerlemek için öngörülebilir bir yol sunarsınız. Sunsetting son adımdır: eski sürüm yayımlanmış bir tarihte kapatılır. AI tarafından oluşturulan backend'lerde uç noktalar ve şemalar hızlıca evrilebildiğinden, sıkı bir emekliye ayırma süreci güveni ve güvenliği korur.

"Major" ne demek, tanımlayın (Semantik Versiyonlama)

API sözleşmesi düzeyinde semantik versiyonlamayı kullanın, sadece repoda değil:

  • MAJOR: herhangi bir kırıcı değişiklik (alan/uc nokta kaldırma, bir alanın anlamını değiştirme, doğrulamanın sıkılaştırılması, auth gereksinimlerinin değişmesi, istemcilerin güvendiği varsayılan davranışın değiştirilmesi).
  • MINOR: geriye dönük uyumlu eklemeler (yeni isteğe bağlı alanlar, yeni uç noktalar, istemcilerin bilinmeyenleri yoksayabileceği ek enum değerleri, yeni filtre parametreleri).
  • PATCH: sözleşmeyi veya gözlemlenebilir davranışı değiştirmeyen hata düzeltmeleri ve fonksiyonel olmayan iyileştirmeler (performans, dahili refactorlar).

Bu tanımı dokümanlarınızda bir kez koyun ve tutarlı uygulayın. Bu, AI destekli değişikliklerin "sessiz major" olmasını engeller.

Pratik bir emekliye ayırma zaman çizelgesi

Kullanıcıların plan yapabilmesi için varsayılan bir politika seçin ve ona bağlı kalın. Yaygın bir yaklaşım:

  • Deprecation duyurusu: yeni sürüm yayınlandığı anda duyurun.
  • Deprecation penceresi: eski sürümü 90–180 gün boyunca çalışır tutun (kurumsal müşteriler için daha uzun).
  • Sunset tarihi: baştan kesin bir kapanış tarihi yayınlayın.

Emin değilseniz biraz daha uzun bir pencere seçin; sürümü kısa süre açık tutmanın maliyeti genellikle acil istemci migrasyonlarının maliyetinden düşüktür.

Deprecation sinyalleri (görmezden gelinmesi zor olsun)

Herkes release notlarını okumadığı için birden fazla kanal kullanın:

  • Yanıt header'ları: örn. Deprecation: true ve Sunset: Wed, 31 Jul 2026 00:00:00 GMT, ayrıca Link: /docs/api/v2/migration gibi metinler.
  • Doküman banner'ları: eski versiyon dokümanlarında kapanış tarihi ve geçiş kontrol listesi içeren açık bir banner.
  • SDK uyarıları: resmi SDK'larda (runtime log + mümkünse derleme zamanı deprecation annotasyonları) uyarılar.

Ayrıca changelog ve durum güncellemelerine deprecaton notları ekleyin ki satın alma ve operasyon ekipleri görsün.

Kaldırma: kesin bir tarihle kapatma (ve güvenli bir son durum)

Eski sürümü sunayt tarihinde çalıştırmayı kesin ve bilinçli kapatın—kazara bozma yoluyla değil.

Sunset'te:

  • Eski sürüm için net bir hata döndürün (ör. 410 Gone) ve en yeni sürüme ve geçiş rehberine işaret eden bir açıklama sağlayın.
  • Bir süre insan okunabilir açıklama sayfası tutun (ör. /docs/deprecations/v1).

En önemlisi, emekliye ayırmayı sahipleri, izleme ve geri alma planı olan planlı bir değişiklik olarak ele alın. Bu disiplin, sık değişimleri istemcileri şaşırtmadan mümkün kılar.

Kazara kırıcı değişiklikleri önleyen testler

AI tarafından üretilen kod hızlı değişebilir—bazen şaşırtıcı yerlerde. İstemcilerin çalışmaya devam etmesini sağlamanın en güvenli yolu, implementasyonu değil sözleşmeyi (dışarı vaat ettiklerinizi) test etmektir.

Sözleşme testleri: spec- vs-spec karşılaştırmaları

Pratik bir temel, önceki OpenAPI spec'i ile yeni üretileni karşılaştıran bir sözleşme testidir. "önce vs. sonra" kontrolü gibi davranır:

  • Kaldırılan uç noktaları, yeniden adlandırılmış alanları, sıkılaştırılmış doğrulama kurallarını veya değişen auth gereksinimlerini tespit eder
  • Yanıt-kodu değişikliklerini işaretler (ör. 200 → 204 veya 404 davranışındaki değişimler)
  • İsteğe bağlı bir alanın artık zorunlu hale gelmesi gibi ince kaymaları yakalar

Pek çok ekip CI'de OpenAPI diff otomasyonu çalıştırır; böylece üretilen hiçbir değişiklik inceleme olmadan dağıtılamaz. Bu, prompt'lar, şablonlar veya model sürümleri değiştiğinde özellikle faydalıdır.

Tüketici odaklı sözleşme testi (plain terimlerle)

Tüketici odaklı sözleşme testi perspektifi ters çevirir: backend ekibinin API'yi istemcilerin nasıl kullandığını tahmin etmesi yerine, her istemci küçük bir beklenti seti (gönderdiği istekler ve güvendiği yanıtlar) paylaşır. Backend, sürümden önce bu beklentileri karşılamaya devam ettiğini kanıtlamalıdır.

Bu, birden fazla tüketici (web uygulaması, mobil uygulama, ortaklar) varsa ve her dağıtımı koordine etmeden güncelleme yapmak istiyorsanız iyi çalışır.

Yanıt şekilleri ve hatalar için regresyon testleri

Aşağıdakileri kilitleyen regresyon testleri ekleyin:

  • Yanıt JSON yapısı (alan adları, tipler, iç içe yapılar)
  • Varsayılanlar ve null olabilirlik (eksik vs null)
  • Sayfalama ve sıralama semantiği
  • Hata formatları: sabit hata kodları, mesaj yapısı ve doğrulama hata alanları

Bir hata şeması yayımlıyorsanız, onu açıkça test edin—istemciler hataları beklenenden daha fazla parse ediyor olabilir.

Dağıtım öncesi CI kapıları

OpenAPI diff kontrollerini, tüketici sözleşmelerini ve şekil/hata regresyon testlerini bir CI kapısında birleştirin. Üretilen bir değişiklik başarısız olursa, düzeltme genellikle prompt'u, üretim kurallarını veya bir uyumluluk katmanını ayarlamak olur—kullanıcılar fark etmeden önce.

Sürümler arası davranış ve hata işleme kararlılığı

İstemciler API ile entegre olduklarında genellikle hata mesajlarını okumazlar—hata şekline ve kodlarına tepki verirler. İnsan dostu bir mesajdaki yazım hatası can sıkıcıdır ama tolere edilebilir; durum kodu değişikliği, eksik alan veya yeniden adlandırılmış bir hata tanımlayıcısı ise geri kazanılabilir bir durumu kırılmış bir ödeme, başarısız bir senkronizasyon veya sonsuz yeniden deneme döngüsüne dönüştürebilir.

Kararlı hatalar: makine-okunabilirliği önceliklendirin

Tutarlı bir hata zarfı (JSON yapısı) ve istemcilerin güvenebileceği sabit tanımlayıcılar tutmayı hedefleyin. Örneğin { code, message, details, request_id } döndürüyorsanız, bu alanları yeni sürümde kaldırmayın veya yeniden adlandırmayın. message içeriğini iyileştirebilirsiniz ama code semantiğini sabit ve dokümante edilmiş tutun.

Zaten birden fazla format yayındaysa, "onu yerinde temizleme" dürtüsüne direnin. Bunun yerine, yeni formatı bir sürüm sınırının arkasında veya bir müzakere mekanizması ile (ör. Accept header) tanıtın ve eskisini desteklemeye devam edin.

Yeni hata kodları eklemek: eski istemcileri kırmadan

Yeni hata kodları gerekli olabilir, ancak bunları istemcileri şaşırtmayacak şekilde ekleyin:

  • Eski kodları geçerli tutun: istemciler VALIDATION_ERROR ile başa çıkıyorsa, bunu aniden INVALID_FIELD ile değiştirmeyin.
  • Daha spesifik varyantlar ekleyin: yeni code döndürün ama geriye dönük uyumluluk için details içinde eski genelleyici koda dair ipuçları verin (veya eski koda map edin).
  • Bir “fallback” kuralı dokümante edin: istemcilere bilinmeyen kodları HTTP statüsüne göre genel bir sınıfa dönüştürmelerini söyleyin (400/401/403/404/409/429/500) ve message'ı göstermek gibi.

Kesinlikle mevcut bir kodun anlamını değiştirmeyin. Eğer NOT_FOUND daha önce "kaynak yok" demekse, onu "erişim reddedildi" için kullanmayın (bu 403 olmalı).

Davranış kararlılığı: varsayılanlar sessizce değişmemeli

Geriye dönük uyumluluk aynı isteğe aynı sonucu vermektir. Görünüşte küçük varsayılan değişiklikler bile istemcileri kırabilir.

Sayfalama: varsayılan limit, page_size veya cursor davranışını sürümlemeden değiştirmeyin. Sayfa tabanlıdan cursor tabanlıya geçiş kırıcıdır; her iki yolu da koruyun.

Sıralama: varsayılan sıralama kararlı olmalıdır. created_at desc'den relevance desc'e geçmek listelerin yeniden sıralanmasına ve UI varsayımlarının veya artımlı senkronizasyonun bozulmasına neden olabilir.

Filtreleme: örtük filtreleri değiştirmeyin (ör. varsayılan olarak “inactive” öğeleri dışlamak). Yeni davranış gerekiyorsa, açık bir flag ekleyin, örn. include_inactive=true veya status=all.

Yaygın tuzaklar: saat dilimleri, sayı formatları ve booleanlar

Bazı uyumluluk sorunları uç noktalardan ziyade yorumlamayla ilgilidir.

  • Saat dilimleri: zaman damgalarının UTC mi olduğunu veya offset içerip içermediğini her zaman belirtin ve tutarlı olun. Lokal zamandan UTC'ye geçiş haber verilmeden yapılırsa yinelenen veya eksik olaylar oluşabilir.
  • Sayı formatları: JSON sayıları açık olsa da, sayılara benzeyen string'ler (para, ondalıklar) değişkenlik gösterebilir. "9.99"'u 9.99'a (veya tersi) dönüştürmeyin.
  • Boolean varsayılanlar: include_deleted=false veya send_email=true gibi varsayılanlar tersine çevrilmemeli. Değişiklik gerekiyorsa istemcinin yeni parametre ile opt-in yapmasını zorunlu kılın.

AI tarafından oluşturulan backend'lerde model, yanıtları "iyileştirme" eğiliminde olabilir; bu yüzden bu davranışları açık sözleşmeler ve testlerle kilitleyin.

Gerçek dünyada uyumluluğu izleme: gözlemlenebilirlik

Reduce accidental breaking changes
Add fields and endpoints confidently with repeatable prompts and clear diffs in your workflow.

Geriye dönük uyumluluğu bir defa doğrulayıp unutmayın. AI tarafından üretilen backend'lerde davranış el yapımı sistemlerden daha hızlı değişebileceği için kim neyi kullanıyor ve bir güncellemenin istemcilere zarar verip vermediği gösteren geri bildirim döngülerine ihtiyacınız var.

API sürümüne göre (ve uç nokta bazında) metrikleri takip edin

Her isteğe açık bir API sürümü (yol: /v1/..., header: X-Api-Version veya müzakere edilen şema sürümü) etiketi koyun. Sonra sürüme göre segmentlenmiş metrikler toplayın:

  • Kullanım: sürüme ve route'a göre istek/dakika
  • Gecikme: sürüme göre p50/p95
  • Hata oranları: sürüme göre 4xx vs 5xx

Böylece örneğin /v1/orders trafikte sadece %5 görünür ama rollout sonrası hataların %70'ini oluşturuyorsa bunu fark edebilirsiniz.

Eski alanları veya uç noktaları kullanan istemcileri tespit edin

API gateway veya uygulamanızı, istemcilerin gerçekten ne gönderdiğini ve hangi rotaları çağırdığını loglayacak şekilde instrument edin:

  • Deprecate edilmiş uç noktalara gelen istekler (örn. /v1/legacy-search)
  • Deprecated alanları içeren payload'lar
  • Yeni isteğe bağlı alanları eksik gönderen istekler

SDK'ları kontrol ediyorsanız, güncel olmayan entegrasyonları tespit etmek için hafif bir istemci tanımlayıcı + SDK sürüm header'ı ekleyin.

Değişikliği tespit etmek için log ve tracing kullanın

Hata arttığında cevaplamak isteyeceksiniz: “Hangi dağıtım davranışı değiştirdi?” Aşağıdakilerle pikleri ilişkilendirin:

  • release tanımlayıcıları (commit hash/build id)
  • versiyon, route ve doğrulama hatalarını içeren yapılandırılmış loglar
  • gecikme veya exception'ın nerede ortaya çıktığını gösteren dağıtık trace'ler (gateway → handler → DB)

Üretilmiş dağıtımlarda geri alma

Geri almaları sade tutun: her zaman önceki üretilmiş artifact'ı (container/image) yeniden dağıtabilin ve trafiği router üzerinden geri çevirin. Veri geri dönüşü gerektiren geri almalardan kaçının; şema değişiklikleri varsa additive DB migrasyonlarını tercih edin ki eski sürümler çalışmaya devam etsin.

Platformunuz environment snapshot'ları ve hızlı geri alma destekliyorsa bunları kullanın. Örneğin Koder.ai workflow'unda snapshot'lar ve rollback özellikleri bulunur; bu, “expand → migrate → contract” veritabanı değişiklikleri ve kademeli API rollouts ile doğal bir uyum sağlar.

AI tarafından üretilen API'leri evrimleştirmek için tekrarlanabilir bir iş akışı

AI tarafından üretilen backend'ler hızla değişebilir—yeni uç noktalar ortaya çıkar, modeller kayabilir, doğrulamalar sıkılaşabilir. İstemcileri kararlı tutmanın en güvenli yolu API değişikliklerini tek seferlik düzenlemeler gibi değil, küçük ve tekrarlanabilir bir sürüm süreci olarak ele almaktır.

İş akışı (öneri → emekliye ayırma)

  1. Değişikliği önerin

Nedenini, hedeflenen davranışı ve kesin sözleşme etkisini (alanlar, tipler, zorunlu/isteğe bağlı, hata kodları) yazın.

  1. Sınıflandırın

Bunu uyumlu (güvenli) veya kırıcı (istemci değişikliği gerektirir) olarak işaretleyin. Emin değilseniz kırıcı sayın ve bir uyumluluk yolu tasarlayın.

  1. Uyumluluk planını tasarlayın

Eski istemcileri nasıl destekleyeceğinize karar verin: alias'lar, dual-write/dual-read, varsayılan değerler, toleranslı parse etme veya yeni bir sürüm gibi.

  1. Koruyucu önlem arkasında uygulayın

Değişikliği feature flag'ler veya konfigürasyon ile ekleyin ki kademeli açıp kapatabilelim.

  1. Sözleşmeyi test edin

Otomatik sözleşme kontrolleri (OpenAPI diff kuralları) ve bilinen istemci istek/yanıt testleri çalıştırın.

  1. Belgelerle birlikte yayımlayın

Her sürüm şu bilgileri içermeli: güncellenmiş referans dokümanları /docs, ilgili migration notu ve değişikliğin uyumlu olup olmadığına dair kısa bir changelog girdisi.

  1. Emekliye ayırın ve zamanında kaldırın

Deprecation'ı duyurun, kalan kullanımı ölçün ve sunset penceresinden sonra kaldırın.

Küçük örnek: alanı yeniden adlandırmadan kırmamak

last_name'i family_name yapmak istiyorsanız:

  • İstek işleme: her iki alanı da kabul edin; ikisi birlikte gelirse family_name'i tercih edin.
  • Yanıt işleme: geçiş süresince her ikisini de döndürebilir veya family_name döndürüp last_name'i alias olarak tutabilirsiniz.
  • Depolama: ikisini aynı dahili kolona map edin.
  • Doküman + changelog: yeni adı dokümante edin, last_name'i kullanımdan kaldırılmış olarak işaretleyin ve kaldırma tarihini yayınlayın.

Eğer teklifiniz plan bazlı destek veya uzun dönem sürüm desteği içeriyorsa, bunu açıkça /pricing üzerinde belirtin.

SSS

What does “backward compatible” mean for an API?

Geriye dönük uyumluluk, mevcut istemcilerin herhangi bir değişiklik yapmadan çalışmaya devam etmesi demektir. Pratikte genellikle şunlar yapılabilir:

  • Yeni, isteğe bağlı yanıt alanları eklemek
  • Yeni uç noktalar eklemek
  • Güvenli varsayılanlarla yeni isteğe bağlı istek alanları eklemek

Genellikle alanların yeniden adlandırılması/çıkarılması, tip değişiklikleri veya doğrulamanın sıkılaştırılması birilerinin bozulmasına yol açar ve bunlar yapılamaz.

What are the most common breaking changes in real APIs?

Herhangi bir dağıtılmış istemcinin güncelleme gerektirmesine neden olacak değişiklikleri kırıcı olarak ele alın. Sık rastlanan kırıcı değişiklikler:

  • Alanların yeniden adlandırılması (ör. statusstate)
  • Bir alanın tipinin değişmesi (string → number)
  • İsteğe bağlı bir alanın zorunlu yapılması
  • Varsayılan davranışın değişmesi (sıralama, sayfalama, filtreleme)
  • Kimlik doğrulama gereksinimleri veya hata formatlarının değişmesi
How do you keep an AI-generated backend from “drifting” over time?

Bir API sözleşmesini sabit tutun, tipik olarak:

  • OpenAPI (REST)
  • JSON Schema (yükleme doğrulaması)
  • GraphQL şeması

Sonrasında:

  • Spec'i repoda saklayın
  • Spec farklarını pull request ile inceleyin
  • Sunucu şablonlarını ve (mümkünse) SDK'ları aynı kaynaktan üretin

Bu, AI ile yeniden üretimin istemciye görünür şekilde davranışı gizlice değiştirmesini engeller.

Should I use contract-first or code-first when AI is generating code?

Contract-first'te önce spec güncellenir, sonra kod üretilir/uygulanır. Code-first'te spec koddan türetilir.

AI iş akışları için pratik bir hibrit:

  • AI'ye kod değişikliği önermesine izin verin
  • Aynı zamanda spec'i güncellemesini/zenginleştirmesini zorunlu kılın
  • Sözleşme diff'ini temel inceleme maddesi olarak ele alın
How can CI catch accidental breaking changes from regenerated code?

CI'de OpenAPI diff kontrolünü otomatikleştirin ve şu tip değişikliklerde build'leri başarısız sayın:

  • Uç noktaların/alanların çıkarılması
  • Alanların yeniden adlandırılması
  • Tip/nullability değişiklikleri
  • Yeni zorunlu alanlar
  • Kimlik doğrulama veya yanıt kodu değişiklikleri

Birleştirmelere yalnızca (a) değişiklik uyumlu onaylandıysa veya (b) yeni bir major sürüme geçiliyorsa izin verin.

What versioning strategy is recommended, and why?

URL sürümlendirme (ör. /v1/orders, /v2/orders) genellikle en az sürpriz yapan yaklaşımdır:

  • İstemcilerin anlaması kolaydır
  • Loglardan hata ayıklaması basittir
  • Yönlendirme ve cache ile iyi çalışır

Header veya query sürümlendirme de mümkün, ama hata ayıklamada ve örneklerde gözden kaçması daha olasıdır.

How should I handle adding new enum values without breaking clients?

Bazı istemcilerin katı olduğunu varsayın. Daha güvenli kalıplar:

  • Mevcut alanları değiştirmek yerine yeni alanlar eklemeyi tercih edin
  • Eski değerleri geçerli tutun; yeni değerleri eklenti olarak ekleyin
  • İstemcilere bilinmeyen enum değerlerini “diğer/bilinmeyen” olarak ele almalarını söyleyen bir kural dokümante edin

Eğer bir enum değerinin anlamını değiştirmek veya bir değeri kaldırmak gerekiyorsa, bunu yeni bir sürümün arkasında yapın.

What’s a safe database migration approach that won’t break API clients?

“Expand → migrate → contract” yaklaşımını kullanın:

  1. Yeni kolon/tablolar ekleyin (eski olanları kaldırmayın)
  2. Mevcut satırları backfill yapın
  3. Hem eski hem yeni yere yazın (dual-write)
  4. Okumaları yeni kaynaktan yapmaya başlayın
  5. İstemciler geçtikten sonra eskileri temizleyin

Bu, kesintisiz geçiş ve geri alma imkânı sağlar.

How do feature flags and gradual rollouts help with backward compatibility?

Feature flag'ler iç davranışı değiştirirken uç nokta şeklini sabit tutmanızı sağlar. Pratik bir dağıtım:

  • Kodu bir flag'in arkasında gönderin (varsayılan kapalı)
  • Canary veya %1 trafik ile başlayın
  • Monitor ederken kademeli olarak arttırın
  • Hemen flag'i kapatarak geri alın

Bu, daha sıkı doğrulama veya performans yeniden yazımları için özellikle faydalıdır.

How should I deprecate and sunset old API versions safely?

Kullanımı gözle görünür hale getirin ve zaman bağlı bir pencere belirleyin:

  • Yeni sürüm yayınlandığında duyurun
  • Eski sürümü belirli bir süre (çoğunlukla 90–180 gün) çalışır tutun
  • Deprecation'ı response header'larında sinyal edin (ör. Deprecation: true, Sunset: Wed, 31 Jul 2026 00:00:00 GMT, Link: /docs/api/v2/migration)
  • Sunset tarihinde eski sürüme net bir hata döndürün (genelde 410 Gone) ve geçiş rehberi sağlayın

Related posts