6 dk

Go API hata işleme kalıpları: net ve tutarlı yanıtlar

Tipli hatalar, HTTP durum kodları, istek kimlikleri ve iç bilgileri sızdırmayan güvenli mesajları standartlaştıran Go API hata işleme kalıpları.

Go API hata işleme kalıpları: net ve tutarlı yanıtlar

Tutarsız API hataları neden istemcileri sinirlendirir

Her endpoint hata durumlarını farklı raporlarsa, istemciler API'ye güvenmeyi bırakır. Bir rota { "error": "not found" } döndürür, başka bir rota { "message": "missing" } döndürür, üçüncüsü ise düz metin gönderir. Anlam yakın olsa bile, istemci kodu ne olduğunu tahmin etmek zorunda kalır.

Maliyetler çabuk ortaya çıkar. Ekipler kırılgan ayrıştırma mantıkları kurar ve endpoint başına özel vakalar ekler. Tekrar denemeler riskli hale gelir çünkü istemci “daha sonra tekrar dene” ile “girdi hatalı”yı ayırt edemez. Destek talepleri artar çünkü istemci belirsiz bir mesaj görür ve ekibiniz bunu sunucu log satırıyla kolayca eşleştiremez.

Yaygın bir senaryo: bir mobil uygulama kayıt sırasında üç endpoint çağırır. İlki alan düzeyinde bir hata haritasıyla HTTP 400 döndürür, ikincisi bir stack trace içeren HTTP 500 döndürür, üçüncüsü { "ok": false } ile HTTP 200 döndürür. Uygulama ekibi üç farklı hata işleyicisi gönderir ve backend ekibi hâlâ “kayıt bazen başarısız oluyor” gibi nereden başlayacağını bilmediği raporlar alır.

Amaç tek, öngörülebilir bir sözleşme. İstemciler ne olduğunu, hatanın kendilerinden mi yoksa bizden mi kaynaklandığını, yeniden denemenin mantıklı olup olmadığını ve destek için yapıştırılabilecek bir istek kimliğini güvenle okuyabilmeliler.

Kapsam notu: Bu yazı JSON HTTP API'lerine odaklanır (gRPC değil), fakat aynı fikirler sistemlere hata döndürdüğünüz her yerde geçerlidir.

Basit hedef: her endpointin uyması gereken tek bir sözleşme

Hatalar için tek, net bir sözleşme seçin ve her endpointin buna uymasını sağlayın. “Tutarlı” olmak, aynı JSON yapısı, alanların aynı anlamı ve hangi handler başarısız olursa olsun aynı davranış demektir. Bunu yaptığınızda, istemciler tahmin etmeyi bırakır ve hataları düzgünce işler.

Kullanışlı bir sözleşme istemcinin bir sonraki adımı nasıl atacağını söylemelidir. Çoğu uygulama için her hata yanıtı üç soruyu yanıtlamalıdır:

  • Girdimi düzeltebilir miyim?
  • Daha sonra yeniden denemeli miyim?
  • Destek ile iletişime geçmem gerekiyor mu?

Pratik kurallar:

  • Tüm hatalar için tek bir yanıt şeması.
  • Tek bir durum kodu politikası (aynı hata tipi her zaman aynı HTTP durumuna eşlenir).
  • Tek bir güvenli mesaj politikası (kullanıcıların görebileceği ile içerde kalacak arasındaki ayrım).
  • Tek bir korelasyon kancası (destek bulabilsin diye döndürülen bir istek kimliği).

Hangi öğelerin asla yanıtlarda görünmeyeceğine önceden karar verin. Yaygın “asla” öğeler: SQL parçaları, stack trace'ler, dahili host adları, gizli veriler ve bağımlılıklardan gelen ham hata dizeleri.

Temiz bir ayrımı koruyun: kısa, kullanıcıya yönelik bir mesaj (güvenli, nazik, yapılabilir) ve iç ayrıntılar (tam hata, stack ve bağlam) loglarda tutulmalı. Örneğin, “Değişiklikleriniz kaydedilemedi. Lütfen tekrar deneyin.” güvenlidir. “pq: duplicate key value violates unique constraint users_email_key” güvenli değildir.

Her endpoint aynı sözleşmeyi takip ettiğinde, istemciler tek bir hata işleyicisi oluşturup her yerde tekrar kullanabilir.

İstemcilerin güvenebileceği bir hata yanıt şeması tanımlayın

İstemciler yalnızca her endpoint aynı yapıda yanıt verirse hataları düzgün işleyebilir. Tek bir JSON zarfı seçin ve onu sabit tutun.

Pratik bir varsayılan, bir error nesnesi artı üst düzey bir request_id'dir:

{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Some fields are invalid.",
    "details": {
      "fields": {
        "email": "must be a valid email address"
      }
    }
  },
  "request_id": "req_01HV..."
}

HTTP durum kodu geniş kategoriyi verir (400, 401, 409, 500). Makine tarafından okunabilir error.code istemcinin dallanabileceği spesifik durumu söyler. Bu ayrım önemlidir çünkü birçok farklı problem aynı durumu paylaşabilir. Bir mobil uygulama hem EMAIL_TAKEN hem de WEAK_PASSWORD için farklı UI gösterebilir, her ikisi de 400 olsa bile.

error.message kısa ve insan tarafından okunabilir olmalı. Kullanıcının problemi düzeltmesine yardımcı olmalı, fakat asla iç bilgileri sızdırmamalıdır (SQL, stack trace, sağlayıcı isimleri, dosya yolları).

İsteğe bağlı alanlar öngörülebilir kaldığı sürece faydalıdır:

  • Doğrulama hataları: alan adına göre mesajların olduğu details.fields.
  • Oran sınırlaması veya geçici sorunlar: details.retry_after_seconds.
  • Ek rehberlik: düz metin olarak details.docs_hint (URL değil).

Geriye dönük uyumluluk için error.code değerlerini API sözleşmenizin bir parçası olarak ele alın. Yeni kodlar ekleyin ama eski anlamları değiştirmeyin. Sadece isteğe bağlı alanlar ekleyin ve istemcilerin tanımadıkları alanları yoksayacaklarını varsayın.

Go'da tipli hatalar: handler'larınız için temiz bir model

Her handler kendi başarısızlık sinyalleme yolunu uydurduğunda hata işleme karmaşıklaşır. Küçük bir tipli hata seti bunu düzeltir: handler'lar bilinen hata tiplerini döndürür, tek bir yanıt katmanı bunları tutarlı yanıtlara çevirir.

Pratik bir başlangıç seti çoğu endpoint'i kapsar:

  • ValidationError (kötü girdi)
  • NotFoundError (kaynak yok)
  • ConflictError (benzersiz kısıtlama, durum uyuşmazlığı)
  • UnauthorizedError (giriş yok ya da yetkisiz)
  • InternalError (diğer tüm durumlar)

Anahtar nokta üst seviyede istikrar sağlamak, kök neden değişse bile. Alt seviye hataları (SQL, ağ, JSON ayrıştırma) sarabilirsiniz ama middleware yine de tespit edebileceği aynı genel tipi alır.

type NotFoundError struct {
	Resource string
	ID       string
	Err      error // private cause
}

func (e NotFoundError) Error() string { return "not found" }
func (e NotFoundError) Unwrap() error { return e.Err }

Handler'ınızda sql.ErrNoRows'u doğrudan sızdırmak yerine NotFoundError{Resource: "user", ID: id, Err: err} döndürün.

Hataları kontrol ederken errors.As kullanmayı tercih edin ve sentinel hatalar için errors.Is kullanın. Basit durumlar için sentinel hatalar (ör. var ErrUnauthorized = errors.New("unauthorized")) işe yarar, ama hangi kaynağın eksik olduğunu gibi güvenli bağlam gerektiğinde özel tipler daha iyidir çünkü genel kamu yanıt sözleşmenizi değiştirmeden bağlam eklemenizi sağlar.

Ekleyecekleriniz konusunda katı olun:

  • Kamuya açık (istemcinin görebileceği): kısa mesaj, sabit kod ve bazen doğrulama için alan adı.
  • Özel (sadece loglar): altyapı Err, stack bilgisi, ham SQL hataları, tokenlar, kullanıcı verileri.

Bu ayrım, istemcilere yardımcı olurken iç bilgileri ifşa etmemenizi sağlar.

Hata tiplerini HTTP durum kodlarına tutarlı şekilde eşleyin

Tipli hatalara sahip olduktan sonra, bir sonraki iş sıkıcı ama gerekli: aynı hata tipi her zaman aynı HTTP durumu üretmeli. İstemciler buna göre mantık kuracak.

Çoğu API için işe yarayan pratik eşleme:

Hata tipi (örnek)DurumNe zaman kullanılır
BadRequest (bozuk JSON, eksik zorunlu query param)400İstek temel protokol veya format düzeyinde geçersiz.
Unauthenticated (token yok/geçersiz)401İstemcinin kimlik doğrulaması gerekiyor.
Forbidden (izin yok)403Kimlik doğrulama geçerli ama erişim yasak.
NotFound (kaynak ID yok)404İstenen kaynak yok (veya varlığını gizlemeyi seçtiniz).
Conflict (benzersiz kısıtlama, sürüm uyuşmazlığı)409İstek iyi biçimlendirilmiş ama mevcut durumla çakışıyor.
ValidationFailed (alan kuralları)422Yapı doğru ama iş doğrulaması başarısız.
RateLimited429Belirli bir zaman penceresinde çok fazla istek.
Internal (bilinmeyen hata)500Hata veya beklenmedik arıza.
Unavailable (bağımlılık down, zaman aşımı, bakım)503Geçici sunucu tarafı sorun.

İki ayırım pek çok karışıklığı önler:

  • 400 vs 422: İsteği güvenilir şekilde yorumlayamıyorsanız 400 kullanın (bozuk JSON, yanlış tipler). İsteği ayrıştırabiliyorsanız ama değerler kabul edilemezse 422 kullanın.
  • 409 vs 422: Alan düzeyi doğrulama için 422; veri geçerli ama mevcut duruma uygulanamıyorsa 409.

Tekrar deneme rehberliği önemlidir:

  • Genelde yeniden denenebilir: 503 ve bazen 429 (bekledikten sonra).
  • Genelde değişiklik olmadan yeniden denenmemeli: 400, 401, 403, 404, 409, 422.
  • Eğer işlem idempotent ise (aynı gövde ile PUT veya idempotency anahtarlı POST), geçici hatalarda yeniden denemek daha güvenli hale gelir.

İstek kimlikleri: istemci sorunlarını debug etmenin en hızlı yolu

İnşa edince ödül kazan
Koder.ai ile inşa ettiklerinizi paylaşın ve inşa etmeye devam etmek için kredi kazanın.

İstek kimliği (request ID), bir API çağrısını uçtan uca tanımlayan kısa benzersiz değerdir. İstemciler her yanıtta bunu görebiliyorsa, destek basitleşir: “İstek kimliğini gönderin” genellikle tam log satırını bulmak için yeterlidir.

Bu alışkanlık hem başarılı hem de hatalı yanıtlarda işe yarar.

Oluşturma ve yayma kuralları

Tek bir net kural kullanın: istemci bir istek kimliği gönderirse onu koruyun. Göndermediyse yeni bir kimlik oluşturun.

  • Gelen ID'yi tek bir header adından kabul edin (bir tane seçin ve dokümante edin, örn. X-Request-Id).
  • Header eksik veya boşsa, kenarda (middleware) yeni bir ID oluşturun ve request context'e ekleyin.
  • ID'yi isteğin ortasında değiştirmeyin. DB veya diğer servislere context veya header yoluyla aktarın.

İstek kimliğini üç yerde koyun:

  • Yanıt header'ı (kabul ettiğiniz header adı)
  • Yanıt gövdesi (standart şemanızda request_id olarak)
  • Loglar (her log satırında yapılandırılmış bir alan olarak)

Batch ve asenkron işler

Toplu endpoint'ler veya arka plan işleri için üst (parent) bir request ID tutun. Örnek: bir istemci 200 satır yüklüyor, 12 tane doğrulama hatası alıyor ve işler kuyruğa alınıyor. Tüm çağrı için tek bir request_id döndürün ve her iş veya öğe düzeyindeki hataya parent_request_id ekleyin. Böylece bir yüklemenin birden çok göreve yayılması durumunda bile izleme mümkün olur.

İç bilgileri sızdırmadan loglama ve metrikler

İstemciler net, sabit bir hata yanıtına ihtiyaç duyar. Loglarınızsa dağınık gerçeği tutmalı. Bu iki dünyayı ayırın: istemciye güvenli bir mesaj ve kamu hata kodu verin, sunucuda ise iç nedeni, stack ve bağlamı loglayın.

Her hata yanıtı için request_id ile aranabilir bir yapılandırılmış olay loglayın.

Tutarlı tutulması faydalı alanlar:

  • request_id
  • user_id veya account_id (kimlikli ise)
  • genel hata kodu ve HTTP durum
  • handler/route adı ve method
  • iç hata detayı (sarmalanmış neden, doğrulama alan hataları, upstream zaman aşımı)

İç ayrıntıları sadece sunucu loglarında (veya iç hata deposunda) saklayın. İstemci hiçbir zaman ham veritabanı hatası, sorgu metni, stack trace veya sağlayıcı mesajı görmemeli. Çoklu servis çalıştırıyorsanız source (api, db, auth, upstream) gibi dahili bir alan triage'ı hızlandırır.

Gürültülü endpoint'leri ve sık tekrarlanan hata türlerini izleyin. Bir endpoint aynı 429 veya 400'ü dakikada binlerce kez üretebiliyorsa log spam'inden kaçının: tekrarlayan olayları örnekleyin veya beklenen hatalar için seviyeyi düşürün, ama yine de metriklerde sayımlarını tutun.

Metrikler loglardan daha erken sorun yakalar. HTTP durumuna ve hata koduna göre gruplanmış sayıları takip edin ve ani sıçramalara alarm koyun. RATE_LIMITED deploy sonrası 10 kat artarsa, log örneklenmiş olsa bile metrikler sayesinde hızlıca fark edersiniz.

Adım adım: Go'da tutarlı bir hata hattı uygulamak

Refaktör sırasında güvenle değiştirin
Hata şemanızı inceltirken snapshot'lar ve geri alma ile hızlıca yineleyin.

Hataları tutarlı hale getirmenin en kolay yolu onları her yerde “yönetmekten” vazgeçip küçük bir hattın içinden geçirmek. Bu hat, istemcinin gördüğünü ve sizin loglarda ne tuttuğunuzu karar verir.

Hattın 5 pratik adımı

Küçük bir hata kodu setiyle başlayın (örnek: INVALID_ARGUMENT, NOT_FOUND, UNAUTHORIZED, CONFLICT, INTERNAL). Bunları güvenli, kamuya açık alanları (code, safe message, hangi alanın yanlış olduğu gibi isteğe bağlı detaylar) ortaya koyan tipli hatalara sarın. İç nedenleri saklı tutun.

Sonra herhangi bir hatayı (statusCode, responseBody)'ye çeviren tek bir çevirici fonksiyon uygulayın. Burada tipli hatalar HTTP durumlarına eşlenir ve bilinmeyen hatalar güvenli bir 500 yanıtına dönüşür.

Ardından middleware ekleyin:

  • Her isteğin bir request_id'si olduğundan emin olsun
  • Panic'lerden kurtarsın (recover)

Bir panic asla stack trace'i istemciye dökmemeli. Normal bir 500 yanıtı ve genel bir mesaj döndürün, tam panic bilgisini aynı request_id ile loglayın.

Son olarak, handler'larınızı doğrudan yanıt yazmak yerine error dönecek şekilde değiştirin. Bir wrapper handler'ı çağırır, çeviriciyi çalıştırır ve standart formatta JSON yazar.

Kısa kontrol listesi:

  • Güvenli alanlara ve sabit kodlara sahip tipli hatalar tanımlayın.
  • Hataları tek bir yerde durum kodlarına ve yanıt JSON'una çevirin.
  • İstek ID ve panic kurtarma middleware'i ekleyin.
  • Handler'ların hata döndürmesini sağlayın; yanıt yazmayı merkezileştirin.
  • Çevirici ve wrapper için golden test'ler ekleyin.

Golden test'ler sözleşmeyi kilitlediği için önemlidir. Biri daha sonra bir mesajı veya durum kodunu değiştirirse, testler müşteriler etkilenmeden önce başarısız olur.

Örnek: bir endpoint, üç başarısızlık, öngörülebilir yanıtlar

Bir endpoint hayal edin: bir istemci müşteri kaydı oluşturuyor.

POST /v1/customers gövdesi { "email": "[email protected]", "name": "Pat" } gibi. Sunucu her zaman aynı hata şeklini döndürür ve her zaman bir request_id içerir.

1) Doğrulama hatası (400)

E-posta eksik veya yanlış formatta. İstemci alanı vurgulayabilir.

{
  "request_id": "req_01HV9N2K6Q7A3W1J9K8B",
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "Some fields need attention.",
    "details": {
      "fields": {
        "email": "must be a valid email address"
      }
    }
  }
}

2) Çakışma (409)

E-posta zaten mevcut. İstemci oturum açmayı veya başka bir e-posta seçmeyi önerebilir.

{
  "request_id": "req_01HV9N3C2D0F0M3Q7Z9R",
  "error": {
    "code": "ALREADY_EXISTS",
    "message": "A customer with this email already exists."
  }
}

3) Geçici hata (503)

Bir bağımlılık kapalı. İstemci geri planlı yeniden deneme gösterip sakin bir mesaj gösterebilir.

{
  "request_id": "req_01HV9N3X8P2J7T4N6C1D",
  "error": {
    "code": "TEMPORARILY_UNAVAILABLE",
    "message": "We could not save your request right now. Please try again."
  }
}

Tek bir sözleşme ile istemci şöyle tepki verir:

  • 400: details.fields kullanarak alanları işaretle
  • 409: kullanıcıyı güvenli bir sonraki adıma yönlendir
  • 503: yeniden deneme isteğinde bulun ve request_id'yi destek için göster

Destek için aynı request_id iç loglarda gerçek nedeni bulmanın en hızlı yoludur; stack trace veya veritabanı hatalarını ifşa etmeden.

Hata işleme deneyimini kötüleştiren yaygın tuzaklar

İstemcileri en hızlı sinirlendiren şey onları tahmin etmeye zorlamaktır. Bir endpoint { "error": "..." } döndürürken diğeri { "message": "..." } döndürürse, her istemci özel durumlardan oluşan bir yığın haline gelir ve hatalar haftalarca gizlenir.

Tekrarlayan birkaç hata:

  • Hataları gövde içinde gizleyip HTTP 200 döndürmek veya endpoint'ler arasında birden fazla hata şeması kullanmak.
  • Kullanıcı mesajında iç bilgileri ifşa etmek: SQL hataları, stack trace'ler, IP'ler, bağımlılık host adları veya dosya yolları.
  • İnsan dilini tek kimlik olarak kullanmak yerine, istemcilerin anahtarlayabileceği sabit bir code kullanmamak.
  • Hata kodlarını geliştirici takımı rahatça değiştirip istemcileri kırmak.
  • request_id'yi sadece hatalarda eklemek; böylece bir kullanıcı raporu ile başarılı çağrıyı ilişkilendiremezsiniz.

İç bilgileri sızdırmak en kolay düşülen tuzaktır. Handler err.Error() dönmek kolaydır ama bu constraint adı veya üçüncü taraf mesajının üretim ortamında yanıt olarak gitmesine yol açar. Kullanıcı mesajını kısa ve güvenli tutun; detaylı nedeni loglarda bırakın.

Sadece metne güvenmek de yavaşça sorun çıkarır. İstemci İngilizce bir cümleyi ayrıştırmak zorunda kalıyorsa ("email already exists"), metni değiştirince istemci mantığı bozulur. Sabit hata kodları mesajları değiştirip çevirseniz bile davranışı korur.

Hata kodlarını kamu sözleşmenizin bir parçası olarak ele alın. Değiştirmeniz gerekirse yeni bir kod ekleyin ve eski kod bir süre çalışmaya devam etsin. Son olarak, her yanıtta, başarı veya hata fark etmeksizin aynı request_id alanını koyun. Bir kullanıcı "önce çalıştı, sonra bozuldu" dediğinde o tek ID genellikle bir saati kurtarır.

Yayına almadan önce hızlı kontrol listesi

Kayıt senaryosunu test edin
Tek bir spesifikasyondan tutarlı 400, 409 ve 503 yanıtları veren bir signup API'si oluşturun.

Yayın öncesi tutarlılık için hızlı bir kontrol:

  • Her yerde tek bir hata yapısı. Her endpoint aynı JSON alanlarını döndürüyor mu (ör. error.code, error.message, request_id).
  • Sabit hata kodları ve kapsama alanı. Kodlar kısa ve sade olsun (VALIDATION_FAILED, NOT_FOUND, CONFLICT, UNAUTHORIZED). Handler'ların bilinmeyen kod döndürmemesi için test ekleyin.
  • Tek durum eşleme kuralı. Her hata tipinin hangi HTTP durumuna gideceğini tek bir yerde belirleyin.
  • İstek ID iki yönde de. Her isteğe request_id döndürün ve panikler ve zaman aşımı dahil her istekte loglayın.
  • Varsayılan olarak güvenli mesajlar. Kullanıcıya yönelik mesajlar kısa, net ve uygulanabilir olmalı; asla stack trace, SQL hatası veya sağlayıcı isimleri içermemeli.

Bunlardan sonra birkaç endpoint'i elle kontrol edin. Bir doğrulama hatası, eksik kayıt ve beklenmedik hata tetikleyin. Yanıtlar endpoint'ler arasında farklı görünüyorsa (alanlar değişiyor, durum kodları sürükleniyor, mesajlar iç bilgi sızdırıyor) paylaşılmış hattı düzeltmeden yeni özellik eklemeyin.

Pratik bir kural: bir mesaj bir saldırgana yardım ederse ya da normal kullanıcıyı kafa karıştırıyorsa, o mesaj loglarda olmalı, yanıtta değil.

Sonraki adımlar: şimdi standartlaştırın ve sonraki sürümlerde tutarlı kalın

İstemci tarafında her endpointin takip etmesini istediğiniz hata sözleşmesini yazılı hale getirin, API zaten yayındaysa bile. Paylaşılan bir sözleşme (durum, sabit hata kodu, güvenli mesaj ve request_id) istemciler için hataları öngörülebilir kılmanın en hızlı yoludur.

Sonra kademeli olarak taşıyın. Mevcut handler'ları tutun ama hatalarını tek bir eşleyici aracılığıyla kamu yanıt biçiminize çevirin. Bu, büyük bir yeniden yazma yapmadan tutarlılığı artırır ve yeni endpoint'lerin yeni formatlar icat etmesini engeller.

Küçük bir hata kodu kataloğu tutun ve bunu API'nizin bir parçası gibi ele alın. Yeni bir kod eklemek isteyen biri olduğunda hızlıca gözden geçirin: gerçekten yeni mi, adı açık mı ve doğru HTTP durumuna mı eşleniyor?

Sözleşme sürüntüsünü yakalamak için bir kaç test ekleyin:

  • Her hata yanıtı request_id içerir.
  • Durum kodu hata tipine uygun (metne değil tipe göre).
  • error.code mevcut ve katalogdan geliyor.
  • error.message güvenli ve iç detaylar içermiyor.
  • Bilinmeyen hatalar 500 ve genel bir mesaj ile fall back ediyor.

Sıfırdan bir Go backend inşa ediyorsanız, sözleşmeyi erken kilitlemek yardımcı olur. Örneğin, Koder.ai (koder.ai) planlama modunda hata şeması ve kod kataloğu gibi konvansiyonları önceden tanımlamanıza olanak vererek API büyürken handler'ların uyumlu kalmasını sağlar.

SSS

Tutarlı bir hata yanıtı nasıl görünmeli?

Her endpoint için tek bir JSON biçimi kullanın. Pratik bir varsayılan, üst düzey bir request_id ile birlikte code, message ve isteğe bağlı details alanlarına sahip bir error nesnesidir; böylece istemciler güvenilir şekilde ayrıştırıp tepki verebilirler.

API hatalarında iç ayrıntı sızdırmaktan nasıl kaçınırım?

error.message alanını kısa ve kullanıcı için güvenli bir cümle olarak döndürün, gerçek nedeni sunucu loglarında tutun. Ham veritabanı hataları, stack trace'ler, iç host adları veya üçüncü taraf mesajlarını asla döndürmeyin, geliştirme sırasında bile.

HTTP durum kodlarım zaten varsa gerçekten hata koduna ihtiyaç var mı?

Makine mantığı için sabit bir error.code kullanın; HTTP durum kodları geniş kategoriyi belirtir. İstemciler ALREADY_EXISTS gibi error.code değerine göre dallanmalı ve durumu 409 gibi HTTP kodu sadece genel rehber olarak görmelidir.

HTTP 400 ile 422 ne zaman kullanmalıyım?

İstek güvenilir şekilde ayrıştırılamıyorsa (bozuk JSON, yanlış tipler) 400 kullanın. İstek iyi biçimlendirilmiş ama iş kuralları başarısız oluyorsa (geçersiz e-posta formatı, kısa parola) 422 kullanın.

HTTP 409 ile 422 arasındaki fark ne zaman önemli?

Girdi geçerli ama mevcut durumla çakışıyorsa (e-posta zaten kayıtlı, versiyon uyuşmazlığı) 409 kullanın. Alan düzeyinde doğrulama ve değeri değiştirerek çözülebilecek durumlar için 422 kullanın.

Go'da tipli hatalar tutarlılığı nasıl sağlar?

Küçük bir tipli hata seti oluşturun (validation, not found, conflict, unauthorized, internal) ve handler'ların bunları döndürmesini sağlayın. Ardından bu tipleri tek bir paylaşılan çevirici ile HTTP durum kodlarına ve standart JSON yanıt biçimine eşleyin.

İstek kimliklerini nasıl oluşturup döndürmeliyim?

Başarılı veya başarısız her yanıtta request_id döndürün ve sunucudaki her log satırına bunu ekleyin. Bir kullanıcı bir sorun bildirirse, o tek ID genellikle tam başarısızlık yolunu loglarda bulmak için yeterlidir.

Neden `{ "ok": false }` ile 200 döndürmek kötü bir fikir?

Operasyon başarılı olduğunda 200 döndürün; hataları 4xx/5xx ile gösterin. Hataları 200 içinde saklamak, istemcilerin gövde alanlarını ayrıştırmasını zorunlu kılar ve endpoint'ler arasında tutarsız davranışa yol açar.

Hangi hataları istemciler yeniden denemeli, hangilerini denememeli?

Genelde 400, 401, 403, 404, 409 ve 422 için yeniden denemeyi önermeyin; bunlar değişiklik olmadan düzelmez. 503 için tekrar deneyin; 429 bazen bekledikten sonra yeniden denenebilir. Idempotency anahtarları destekleniyorsa, POST gibi işlemler geçici hatalarda daha güvenli şekilde yeniden denenebilir.

API evrildikçe hata yanıtlarının sapmasını nasıl önlerim?

Sözleşmeyi “golden” testlerle kilitleyin: her hata yanıtı request_id içeriyor mu, durum kodu hatanın tipine uygun mu, error.code katalogdaki bir kod mu gibi kontroller ekleyin. Yeni kod eklerken eski davranışları kırmamaya dikkat edin.

Related posts