API'ler, modern uygulamaların bel kemiğidir. Kullanıcı girişinden, bir e-ticaret sitesinde sepete ürün eklemeye kadar her şey, ön yüz (frontend) ve arka yüz (backend) arasındaki API çağrılarıyla gerçekleşir. Her şey yolunda gittiğinde sorun yoktur, peki ya işler ters giderse? "Bir hata oluştu" gibi genel mesajlar, geliştiriciler ve son kullanıcılar için kafa karıştırıcı olabilir. İşte bu noktada, API'lerde standart ve etkili bir hata yönetimi stratejisine ihtiyacımız var.
Bu yazıda, web API'lerinde hata yönetiminin en önemli araçlarından biri olan ProblemDetails kavramını ve bununla birlikte kullanılan HTTP durum kodlarını ele alacağız.
Bir API ucunun yalnızca 200 OK
(başarılı) veya 500 Internal Server Error
(beklenmedik hata) döndürmesi yeterli değildir. Örneğin, bir kayıt formunda kullanıcı, e-posta adresini yanlış formatta girdiğinde, arka yüzün sadece 500
hatası dönmesi yanlıştır. Neden mi? Çünkü bu bir sunucu hatası değil, istemcinin (kullanıcının) yaptığı bir hatadır. Doğru yaklaşım, istemciye "gönderdiğiniz veri hatalı" demek ve bu hatanın nedenini açıklamaktır.
API'ler, istemci hatalarını ve sunucu hatalarını net bir şekilde ayırmalıdır. Bu ayrım için de 4xx
ve 5xx
durum kodları kullanılır.
ProblemDetails (RFC 7807), API'lerden gelen hata yanıtları için standart bir JSON formatıdır. Bu standart, hatanın sadece durum kodunu değil, aynı zamanda başlık, detay ve diğer ilgili bilgileri de içerir. Bu sayede, ön yüz uygulaması hatanın nedenini kolayca anlayabilir ve kullanıcıya özel bir mesaj gösterebilir.
4xx
Hataları: İstemcinin Kontrol Edebileceği Hatalar4xx
ile başlayan HTTP durum kodları, istemciden kaynaklanan hataları işaret eder. ProblemDetails bu hataları açıklamak için mükemmeldir.
400 Bad Request
- Geçersiz İstekBu kod, istemcinin gönderdiği verinin hatalı, eksik veya beklenen formatta olmadığını belirtir. En sık form doğrulama (validation) hataları için kullanılır.
public IResult GecersizVeriGonderimi()
{
// Örnek bir model doğrulama hatası oluşturulur.
return Results.ValidationProblem(new Dictionary
{
{"KullaniciAdi", new[] {"Kullanıcı adı en az 5 karakter olmalıdır."}},
{"Email", new[] {"Geçerli bir e-posta adresi giriniz."}}
});
}
404 Not Found
- Kaynak BulunamadıBu kod, istemcinin erişmeye çalıştığı kaynağın (ürün, kullanıcı, dosya vb.) sunucuda bulunmadığını belirtir.
public IResult KaynakBulunamadi(int id)
{
// Belirli bir ID'ye sahip kaynağın bulunamadığı varsayılır.
return Results.NotFound(new
{
title = "Kaynak Bulunamadı",
detail = $"'{id}' ID'li kaynak veritabanında mevcut değil."
});
}
409 Conflict
- ÇakışmaBu kod, istemcinin isteğinin, sunucudaki mevcut bir durumla çakışması sonucunda iş kuralı ihlali meydana geldiğinde kullanılır.
public IResult KuralIhlali()
{
// Bir iş kuralının ihlal edildiği varsayılır (örn: stokta ürün yok).
return Results.Conflict("Bu ürünün stoğu tükenmiştir.");
}
401 Unauthorized
- Yetkisiz ErişimBu kod, istemcinin kimlik bilgilerini (örneğin, API anahtarı veya JWT) sağlamadığını veya sağladığı bilgilerin geçersiz olduğunu belirtir. Yani, kimlik doğrulama (authentication) başarısız olmuştur.
public IResult YetkisizErisim()
{
var problem = new ProblemDetails
{
Title = "Kimlik Doğrulama Gerekli",
Detail = "Bu kaynağa erişmek için geçerli bir API anahtarı sağlamalısınız.",
Status = StatusCodes.Status401Unauthorized
};
return Results.Problem(problem);
}
403 Forbidden
- Yasaklı ErişimBu kod, istemcinin kimliğinin doğrulandığını ancak istenen kaynağa veya işleme erişim izni olmadığını belirtir. Yani, kullanıcı sisteme girmiştir ancak yetkilendirme (authorization) sorunu vardır.
public IResult YasakliErisim()
{
var problem = new ProblemDetails
{
Title = "Erişim Reddedildi",
Detail = "Bu işlemi gerçekleştirmek için gerekli yetkiye sahip değilsiniz. Lütfen yöneticinize başvurun.",
Status = StatusCodes.Status403Forbidden
};
return Results.Problem(problem);
}
5xx
Hataları: Sunucunun Kontrol Etmesi Gereken Hatalar5xx
ile başlayan HTTP durum kodları, API'nin kendi içinde oluşan ve istemciden bağımsız olan beklenmedik hataları gösterir. Bu hatalar, veritabanı bağlantı sorunları, sunucu çökmeleri veya kodunuzdaki öngörülemeyen hatalardan kaynaklanabilir. ProblemDetails bu hatalarla kullanılmaz.
500
hatasının detayları (hata izi, veritabanı şeması vb.) hassas bilgiler içerir. Bu bilgilerin istemciye sızdırılması büyük bir güvenlik riskidir.Peki, Hataları Nasıl İzleyeceğiz?
İşte bu noktada loglama sistemleri devreye girer. Bir hata oluştuğunda:
500
durum kodunu döner.500
kodunu aldığında, kullanıcıya “Bir hata oluştu, lütfen daha sonra tekrar deneyin.” gibi genel ve dostça bir mesaj gösterir.Bu yaklaşım, hem uygulamanızı güvende tutar hem de hata ayıklama süreçlerini hızlandırır.
HTTP Durum Kodu | Kategori | ProblemDetails Kullanılır mı? | Örnek Senaryo |
---|---|---|---|
400 |
İstemci Hatası | Evet | Geçersiz form verisi veya eksik alanlar. |
404 |
İstemci Hatası | Evet | İstenen kaynağın (ürün, kullanıcı) bulunamaması. |
409 |
İstemci Hatası | Evet | Stokta olmayan bir ürünü alma girişimi. |
401 , 403 |
İstemci Hatası | Evet | Kimlik doğrulama/yetkilendirme sorunları. |
500 |
Sunucu Hatası | Hayır | Veritabanı bağlantı hatası veya beklenmedik bir kod hatası. |
RESTful API tasarımında, her bir CRUD işlemi için doğru HTTP durum kodunu kullanmak, API'yi daha anlaşılır ve öngörülebilir hale getirir. İşte yaygın senaryolar ve onlara karşılık gelen durum kodları:
CRUD İşlemi | Başarılı Yanıt | Hata Durumu 1 | Hata Durumu 2 |
---|---|---|---|
Create (POST) | 201 Created |
400 Bad Request (Geçersiz veri) |
409 Conflict (Tekrar eden veri) |
Read (GET) | 200 OK |
404 Not Found (Kaynak bulunamadı) |
401 Unauthorized (Kimlik doğrulama) |
Update (PUT/PATCH) | 200 OK |
400 Bad Request (Geçersiz veri) |
404 Not Found (Güncellenecek kaynak yok) |
Delete (DELETE) | 204 No Content |
404 Not Found (Silinecek kaynak yok) |
409 Conflict (Kaynak başka bir yerde kullanılıyor) |