# API hata gövdelerimi RFC 7807 problem+json biçimine mi taşımalıyım?

> 7807 yerine onu güncelleyen RFC 9457'yi baz alın, üretimi tek bir exception handler'a toplayın ve `type` URI'sini sözleşme gibi yönetin.

- Soruldu: 2026-09-09
- Yanıtlandı: 2026-09-11
- Soran: Serkan
- Etiketler: api, error-handling, api-design
- Kaynak: https://www.muhammetsafak.com.tr/sor-bakalim/api-hata-govdelerimi-rfc-7807-problem-json-tasimaliyim/
- Dil: tr-TR
- Yazar: Muhammet Şafak

---
**Soru:** Bir platformumuz var ve içindeki her servis (bazıları Laravel, bazıları Go) hataları biraz farklı bir gövdeyle dönüyor: birinde `{"error": "..."}`, ötekinde `{"message": "...", "code": 42}`, bir başkasında iç içe bir `errors` objesi.

İstemci tarafındaki ekipler her servisin hatasını ayrı ayrı parse etmek zorunda kalıyor ve bu sürdürülemez hale geldi. Hata gövdelerini RFC 7807 `application/problem+json` biçimine taşıyarak tek tip bir sözleşme kursam mantıklı olur mu, yoksa gereksiz bir standart yükü mü getirir?


Kısa cevap: Evet, standartlaştırın.

## Kısa cevap

Ama iki şart: 7807 yerine onu güncelleyen (obsolete eden) RFC 9457'yi baz alın ve bunu her endpoint'e elle değil, tek bir merkezi katmanda zorunlu kılın.

## Neden

1. **7807 artık RFC 9457.** Aynı şekil, 2023'te güncellendi. Yeni işlerde 9457'yi referans alın. Alanlar aynı: `type` (URI), `title`, `status`, `detail`, `instance` — ve istediğiniz kadar ekstra (extension) alan koyabilirsiniz.

2. **Asıl kazanç alan isimleri değil, tek tip zarftır.** İstemci ekipleri artık her serviste tek bir şekli parse eder. Sizin derdiniz zaten tam olarak buydu; standardın bütün değeri de burada. Yani evet, yapmaya değer.

## Ne yapmalı

1. **Content-Type'ı doğru set edin: application/problem+json.** İstemciler ve ara proxy'ler bunu normal bir gövdeden ayırt edebilsin. Bu başlığı unutmak, standardı yarım uygulamaktır.

2. **type stabil bir makine anahtarıdır — sözleşme gibi davranın.** Bir URN ya da bir dokümantasyon URL'i kullanın. İstemci `title`/`detail` gibi insan-okunur alanlara değil, `type`'a göre dallanır. `detail` içine stack trace veya iç ayrıntı sızdırmayın; orası [kullanıcıya dönük insan-okunur bir cümledir](/blog/api-hata-sozlesmesi-istemciye-anlamli-hata-dondurmek/).

   ```json
   {
     "type": "https://api.example.com/problems/insufficient-funds",
     "title": "Insufficient funds",
     "status": 422,
     "detail": "Cüzdan 7f3a bakiyesi 12.00, gereken 50.00.",
     "instance": "/wallets/7f3a/withdrawals/9910"
   }
   ```

3. **Tek yerde zorunlu kılın — exception handler / middleware.** Laravel'de (11'den beri `bootstrap/app.php` içindeki `withExceptions()->render()`, öncesinde `Handler`'ın `render` katmanı), Go'da merkezi bir "error → problem" mapper'da üretin. Her endpoint'te ayrı ayrı yazarsanız zamanla drift başlar; standardın anlamı da kaçar.

4. **Validation hataları için extension gerekir.** 9457 alan-bazlı hata listesi tanımlamaz. Doğrulama için bir `errors` dizisi extension'ı ekleyin ve bu şekli bir kez tüm servislerde sabitleyin — yoksa yine servis başına farklılaşır.

5. **Geçişi geriye dönük uyumlu planlayın.** Mevcut istemciler eski gövdeyi bekliyor olabilir. Sunucu tarafında yeni biçime geçmek kolay ama istemciler bir gecede güncellenmez. Yeni `problem+json` biçimini bir API sürümüne bağlayın ya da geçiş penceresinde her iki alanı da (örneğin eski `message` ile yeni `detail`) bir süre birlikte döndürün; istemciler taşındıkça eskisini kaldırın.

6. **Her şeyi standarda boğmayın.** problem+json hata gövdeleri içindir; başarılı yanıtların şeklini değiştirmez. Ayrıca dokümantasyonu da otomatikleştirin: OpenAPI şemanızda `type` kataloğunu referans olarak tanımlayın ki istemciler hangi hata tiplerini bekleyeceklerini sözleşmeden görsün.

**Sonuç:** Ben olsam 9457'yi baz alır, `type` için versiyonlanabilir bir URI şeması belirler, üretimi tek bir exception handler'a toplar ve validation için ortak bir `errors` extension'ı tanımlardım. Migrasyonu da tek seferde değil, `type` kataloğunu doldururken ve istemcileri taşırken kademeli yapardım. Standardın değeri disiplinde: tek zarf, tek üretim noktası, `type`'ı sözleşme gibi yönetmek.

## İlgili Yazılar

- [API hata sözleşmesi: istemciye anlamlı hata döndürmek](/blog/api-hata-sozlesmesi-istemciye-anlamli-hata-dondurmek/) — Blog
- [API yanıtlarını standartlaştırmak: tutarlı bir sözleşme](/blog/api-yanitlarini-standartlastirmak-tutarli-bir-sozlesme/) — Blog
- [OpenAPI şemasını önce mi yazmalıyım yoksa koddan mı üretmeliyim?](https://www.muhammetsafak.com.tr/sor-bakalim/openapi-semasini-once-mi-yazmaliyim-yoksa-koddan-mi-uretmeliyim/) — Sor Bakalım
- [Public API'mde bir endpoint'i kullanımdan kaldırırken sunset sürecini nasıl yönetmeliyim?](https://www.muhammetsafak.com.tr/sor-bakalim/public-apimde-bir-endpointi-kullanimdan-kaldirirken-sunset-surecini-nasil-yonetmeliyim/) — Sor Bakalım
- [Ödeme webhook'u aynı bildirimi tekrar gönderiyor; idempotency'i nasıl kurarım?](https://www.muhammetsafak.com.tr/sor-bakalim/webhook-mukerrer-bildirim-idempotency-ve-hmac/) — Sor Bakalım
