API Tasarımı & Hata Yönetimi 3 dk okuma 3 okunma

REST API'lerde Hata Yönetimi ve Hata Kodları

REST API'lerde etkili hata yönetimi, doğru HTTP durum kodları (4xx istemci, 5xx sunucu), RFC 9457 Problem Details formatı, iş mantığına özel hata kodları ve güvenli hata mesajlarına dayanır. Stack trace ve iç sistem detayları asla istemciye gönderilmemeli; her yanıta trace ID eklenmeli ve hatalar merkezi olarak yönetilmelidir.

REST API'lerde Hata Yönetimi ve Hata Kodları

REST API'lerde Hata Yönetimi ve Hata Kodları

Bir API'nin kalitesi, yalnızca başarılı yanıtlarında değil, hata durumlarındaki davranışında da kendini gösterir. İyi tasarlanmış hata yönetimi; istemcinin sorunu anlamasını, kullanıcıya anlamlı mesaj göstermesini ve gerektiğinde otomatik olarak yeniden denemesini sağlar. Kötü tasarlanmış hata yanıtları ise hata ayıklamayı zorlaştırır ve güvenlik açıklarına yol açar.


1. HTTP Durum Kodları: İlk Katman

HTTP durum kodları, hatanın türü hakkında istemciye ilk ipucunu verir. Temel ayrım kritiktir: 4xx istemcinin düzeltebileceği, 5xx sunucunun düzeltmesi gereken hataları temsil eder.

Kod Anlam Kullanım
400 Bad Request Validasyon hatası, bozuk JSON
401 Unauthorized Token eksik/geçersiz
403 Forbidden Kimlik doğrulandı, yetki yok
404 Not Found Kaynak mevcut değil
409 Conflict Aynı e-posta ile kayıt, eşzamanlı güncelleme
422 Unprocessable Entity Söz dizimi doğru, iş mantığı hatası
429 Too Many Requests Rate limit aşıldı
500 Internal Server Error Beklenmedik sunucu hatası
503 Service Unavailable Bakım, aşırı yük

2. Problem Details (RFC 9457): Standart Hata Formatı

Yalnızca durum kodu dönmek yeterli değildir; istemcinin hatayı anlaması için yapılandırılmış bir gövde gerekir. Problem Details, bu ihtiyacı karşılayan endüstri standardıdır.

json

{
  "type": "https://example.com/probs/validation-error",
  "title": "Validation Error",
  "status": 400,
  "detail": "Bir veya daha fazla alan geçersiz.",
  "instance": "/api/orders",
  "errors": {
    "customerName": ["Müşteri adı boş olamaz."],
    "totalAmount": ["Tutar pozitif olmalıdır."]
  },
  "traceId": "0HN7GNR1Q8Q7D:00000001"
}

Content-Type: application/problem+json

traceId gibi genişletme üyeleri, destek ekibinin log'larda ilgili isteği bulmasını sağlar.


3. İş Mantığı Hataları için Özel Hata Kodları

HTTP durum kodları genel kategorileri temsil eder. İstemcinin iş mantığına özel hataları ayırt edebilmesi için uygulamaya özel hata kodları tanımlanmalıdır.

json

{
  "type": "https://example.com/probs/insufficient-stock",
  "title": "Insufficient Stock",
  "status": 409,
  "detail": "Ürün stoğu yetersiz. Mevcut: 3, İstenen: 10.",
  "errorCode": "ORDER_STOCK_INSUFFICIENT",
  "availableQuantity": 3,
  "requestedQuantity": 10
}

Kurallar:

  • Büyük harf ve alt çizgi kullanın (ORDER_STOCK_INSUFFICIENT).

  • Hiyerarşik yapı kurun (PAYMENT_CARD_EXPIRED).

  • Hata kodlarını sürümler arasında değiştirmeyin.

  • Her kodu dokümante edin.


4. Güvenlik: Hata Mesajlarında Bilgi Sızıntısını Önleme

Hata mesajları, saldırganlara sistem hakkında bilgi sızdırabilir.

❌ Güvensiz:

json

{
  "status": 500,
  "detail": "SqlException: Invalid column name 'user_password' at System.Data.SqlClient..."
}

✅ Güvenli:

json

{
  "type": "https://example.com/probs/internal-error",
  "title": "Internal Server Error",
  "status": 500,
  "detail": "Beklenmedik bir hata oluştu. Lütfen daha sonra tekrar deneyin.",
  "traceId": "0HN7GNR1Q8Q7D:00000001"
}

Kurallar: Stack trace, veritabanı hata mesajları, dosya yolları ve sunucu isimleri asla istemciye gönderilmemeli; gerçek detaylar sunucu log'larına yazılmalıdır.


5. .NET'te Merkezi Hata Yönetimi

.NET 8+ IExceptionHandler ile:

csharp

public class GlobalExceptionHandler : IExceptionHandler
{
    public async ValueTask<bool> TryHandleAsync(
        HttpContext context, Exception exception, CancellationToken ct)
    {
        var problem = exception switch
        {
            NotFoundException => new ProblemDetails
            {
                Title = "Kaynak Bulunamadı",
                Status = StatusCodes.Status404NotFound
            },
            ValidationException v => new ValidationProblemDetails(v.Errors)
            {
                Title = "Doğrulama Hatası",
                Status = StatusCodes.Status400BadRequest
            },
            _ => new ProblemDetails
            {
                Title = "Sunucu Hatası",
                Status = StatusCodes.Status500InternalServerError,
                Detail = "Beklenmedik bir hata oluştu."
            }
        };

        problem.Extensions["traceId"] = context.TraceIdentifier;
        context.Response.StatusCode = problem.Status ?? 500;
        await context.Response.WriteAsJsonAsync(problem, ct);
        return true;
    }
}

// Program.cs
builder.Services.AddExceptionHandler<GlobalExceptionHandler>();
builder.Services.AddProblemDetails();
app.UseExceptionHandler();

6. En İyi Pratikler

Pratik Açıklama
Tutarlı format kullanın Tüm hatalarda Problem Details.
Doğru durum kodu seçin 4xx ve 5xx ayrımına dikkat edin.
Özel hata kodları tanımlayın İş mantığı hatalarını ayırt edin.
Güvenli mesajlar yazın Stack trace ve iç detayları asla göndermeyin.
Trace ID ekleyin Log'larda ilgili isteği bulmayı kolaylaştırın.
Merkezi yönetin IExceptionHandler ile tüm hataları tek noktadan yönetin.
Dokümante edin Her hata kodunu API dokümanında belirtin.

Sonuç

REST API'lerde hata yönetimi, API'nin kullanılabilirliğini ve güvenliğini belirleyen en kritik unsurlardan biridir. Doğru HTTP durum kodları, Problem Details standardı, özel hata kodları, güvenli mesajlar ve merkezi yönetim ile istemcilerin sorunları anlamasını ve düzeltmesini sağlayabilirsiniz. Unutmayın: İyi bir API, hata durumunda bile kullanıcıyı yarı yolda bırakmaz; ona ne olduğunu ve ne yapması gerektiğini açıkça söyler.

Tüm yazılar Soru ya da yorumun mu var? Yaz