---
title: 'Durum Kodları'
source: 'https://academia.sh/tr/kurslar/uygulama-protokolleri/durum-kodlari'
course: 'Uygulama Katmanı Protokolleri'
language: tr
updated: '2026-08-17T18:07:00+00:00'
license: 'CC BY-SA 4.0'
---

# Durum Kodları

Durum satırının ilk basamağı bir yönergedir: aracı gövdeyi hiç açmadan saklama, yönlendirme ve yeniden deneme kararlarını ondan çıkarır.

Önceki ders isteğin alanlarını ölçtü: yöntem, yol, konak. Yanıtın başlık alanlarına bakıldı
ama **ilk satırı** bilerek dışarıda bırakıldı. Aracının bir yanıt üzerinde alacağı ilk karar
o satırdadır ve satırın taşıdığı şey üç basamaklı bir sayıdır.

Bu dersin sorusu şudur: aracı, yanıtın gövdesini hiç açmadan, yalnız o sayının **ilk
basamağına** bakarak ne kadar ileri gidebilir. Gövdeyi de açan bir aracı aynı kararlara mı
varır — varıyorsa fazladan okuduğu baytın karşılığı nedir.

## Durum Satırı

Yanıt, bir durum satırıyla başlar. Aşağıdaki döküm öğretim amaçlıdır ve çalıştırılmaz:

```text
HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 128

HTTP/1.1 301 Moved Permanently
Location: /olcum/kuzey/guncel

HTTP/1.1 503 Service Unavailable
Retry-After: 30
```

Satırın üç parçası vardır: protokolün adı ve sürümü, üç basamaklı **durum kodu**, ve kodun
insan okuması için yazılmış kısa karşılığı. Aracının işine yarayan tek parça ortadaki
sayıdır; sağdaki metin bilgilendirmedir ve karara girmez.

Sayının kendisi de bütün olarak gerekmez. İlk basamak kodun **durum sınıfını (status
class)** verir ve aracının okuduğu asıl şey budur.

## Sınıfın Kendisi Bir Yönergedir

| Sınıf | Anlamı | Aracıya söylediği |
|---|---|---|
| 1xx | Bilgilendirme | Ara yanıt; iletilir, saklanmaz |
| 2xx | Başarı | Yanıt saklamaya uygundur |
| 3xx | Yönlendirme | Kaynağın adresi değişti |
| 4xx | İstemci hatası | Aynı istek aynı sonucu verir, yeniden denemek boşunadır |
| 5xx | Sunucu hatası | Yöntem etkisizse istek yeniden denenebilir |

Bu tablonun kritik özelliği, sağ sütunun **kodun kendisini değil sınıfını** kullanmasıdır.
Aracı 404 ile 400 arasındaki farkı bilmek zorunda değildir; ikisi de dördüncü sınıftandır ve
ikisinde de yeniden deneme boşunadır. Uygulamayı bilmeyen bir katmanın bilebileceği en üst
ayrıntı düzeyi budur ve protokol o düzeyi ilk basamağa yerleştirmiştir.

Birinci sınıf, kurgunun ölçüm kümesine girmez ve bunun bir nedeni vardır: 1xx bir **ara
yanıttır**, alışverişi bitirmez. Aracı onu ne saklar ne de üzerine karar kurar; olduğu gibi
iletir ve nihai yanıtı beklemeyi sürdürür. Ölçülen şey alışveriş başına alınan karar
olduğuna göre, alışverişi bitirmeyen bir yanıt sayıma giremez.

Web API Tasarımı kursunun kaynak tasarımı konusu **hangi kodun seçilmesi gerektiğini**
ölçer: gevşek bir eşlemenin istek sayısını nasıl artırdığını sayar. Burada seçim verilidir;
ölçülen şey, verilmiş bir sınıfın aracıya **kaç kararı aldırdığıdır**.

## Üç Karar

Önceki dersin beş kararı yerinde kalır. Durum satırı üç karar daha açar:

| Karar | Gerçeği belirleyen |
|---|---|
| `saklamaya_uygun` | Yanıt gerçekten başarılı mı |
| `adres_degisti` | Kaynak gerçekten başka bir adrese mi taşındı |
| `yeniden_denenebilir` | Sunucu tarafında mı başarısız oldu ve yöntem etkisiz mi |

Kâhinin gerçeği bunları yanıtın **gerçek sınıfından** okur. Sunucunun bildirdiği kod ise ayrı
bir alandır ve ikisi her zaman uyuşmaz: kurguda birkaç sunucu hatası 200 diye bildirilir.
Bu, kursun her derste hatırlanan okumasının bu dersteki biçimidir — iletide yazanı
doğrulayan hiçbir şey yoktur.

Karar kümesi kırk alışveriş ve sekiz karardan, yani üç yüz yirmi karardan oluşur. Ölçülebilen
en küçük fark $1/320 = 0{,}0031$'dir; bundan küçük bir fark iddia edilmez.

Ölçümün varsayımları:

- **HA7** — Önceki dersin kırk alışverişi ve beş kararı olduğu gibi alınır; üzerine ayrı bir
  üreteçle durum kodu atanır ve ilk beş kararın gerçeği değişmez.
- **HA8** — Durum kodları sabit bir listeden çekilir ve birinci sınıf kümeye girmez: ara
  yanıt alışverişi bitirmez, bitmeyen alışveriş de sayıma giremez.
- **HA9** — Kâhinin gerçeği yanıtın **gerçek sınıfıdır**; sunucunun bildirdiği kod ayrı bir
  alandır ve kurguda kimi sunucu hatası 200 diye bildirilir. Bildirimi doğrulayan bir düzenek
  yoktur.
- **HA10** — İki rejim karşılaştırılır: aracı ya yalnız durum satırını okur, ya gövdeyi de
  açar. Aradaki tek fark sınıfın nereden okunduğudur — kodun ilk basamağından ya da gövdeden.
- **HA11** — Gövde, çözülmüş bir yanıt içeriğini temsil eden sabit yapıda bir alandır ve
  gerçek sınıfı doğru taşır; gövdeyi açmanın baytı bu alanın sayımından gelir.
- **HA12** — Tur bilançosu bir zamanlama ölçümü değil bir sayımdır: üçüncü sınıf yanıtın
  eklediği ve dördüncü sınıf yanıtın sildiği turlar alışveriş sayısından hesaplanır.

## Çekirdeğin Genişletilmesi

Çekirdek önceki dersinkiyle aynıdır; üzerine `durum_ata` işlevi, üç yeni karar ve gövdeyi
gören ikinci bir görünürlük demeti eklenir. `kahin` işlevinin ilk beş satırına
dokunulmamıştır.

```python
TOHUM = 20260809
GUVENLI = {"GET", "HEAD"}
ETKISIZ = {"GET", "HEAD", "PUT", "DELETE"}
YONTEMLER = ["GET", "GET", "GET", "HEAD", "POST", "PUT", "DELETE"]
YOLLAR = ["/olcum/kuzey", "/olcum/yamac", "/ozet", "/kayit", "/oturum"]
DURUMLAR = [200, 200, 200, 201, 204, 301, 400, 404, 500, 503, 503]
TEMEL = ("saklanabilir", "paylasilabilir", "taze", "yinelenebilir",
         "yonlendirilebilir")
DURUM_KARARLARI = ("saklamaya_uygun", "adres_degisti", "yeniden_denenebilir")
KARARLAR = TEMEL + DURUM_KARARLARI
ACIK = ("yontem", "yol", "konak", "ozel_imi", "dogrulayici")
SATIR = ACIK + ("durum",)
SATIR_GOVDE = SATIR + ("govde",)


def uretec(tohum: int):
    d = tohum % 2147483646 + 1

    def r(n: int) -> int:
        nonlocal d
        d = (d * 48271) % 2147483647
        return d % n
    return r


def alisverisler(sayi: int = 40, tohum: int = TOHUM) -> list[dict]:
    r, liste = uretec(tohum), []
    for i in range(sayi):
        yontem, yol = YONTEMLER[r(7)], YOLLAR[r(5)]
        ozel = yol == "/oturum" or r(5) == 0
        degisti = r(3) == 0
        liste.append({
            "no": i + 1, "yontem": yontem, "yol": yol,
            "ozel": ozel, "degisti": degisti,
            "ozel_imi": ozel and r(4) != 0,
            "damga_atladi": degisti and r(6) == 0,
        })
    return liste


def durum_ata(liste: list[dict], tohum: int = TOHUM + 101) -> list[dict]:
    r = uretec(tohum)
    for a in liste:
        kod = DURUMLAR[r(11)]
        gercek = kod // 100
        yanilti = gercek == 5 and r(3) == 0   # sunucu, hatayı 200 diye bildirdi
        a["gercek_sinif"] = gercek
        a["durum"] = 200 if yanilti else kod
        a["yanilti"] = yanilti
    return liste


def kahin(a: dict) -> dict:
    return {
        "saklanabilir": a["yontem"] in GUVENLI and not a["ozel"],
        "paylasilabilir": not a["ozel"],
        "taze": not a["degisti"],
        "yinelenebilir": a["yontem"] in ETKISIZ,
        "yonlendirilebilir": True,
        "saklamaya_uygun": a["gercek_sinif"] == 2,
        "adres_degisti": a["gercek_sinif"] == 3,
        "yeniden_denenebilir": a["gercek_sinif"] == 5 and a["yontem"] in ETKISIZ,
    }


def ileti(a: dict, gorunur: tuple) -> dict:
    tam = {"yontem": a["yontem"], "yol": a["yol"], "konak": "istasyon.ornek",
           "ozel_imi": a["ozel_imi"],
           "dogrulayici": a["degisti"] and not a["damga_atladi"],
           "durum": a["durum"],
           "govde": {"sinif": a["gercek_sinif"], "yol": a["yol"],
                     "ayrinti": "cozumlenmis yanit govdesi",
                     "izleme": f"iz-{a['no']:04d}"}}
    return {k: v for k, v in tam.items() if k in gorunur}


def bayt(i: dict) -> int:
    return sum(len(k) + len(str(v)) + 4 for k, v in i.items())


def araci(i: dict) -> dict:
    k = {}
    if "yontem" in i:
        k["yinelenebilir"] = i["yontem"] in ETKISIZ
    if "ozel_imi" in i:
        k["paylasilabilir"] = not i["ozel_imi"]
        if "yontem" in i:
            k["saklanabilir"] = i["yontem"] in GUVENLI and not i["ozel_imi"]
    if "dogrulayici" in i:
        k["taze"] = not i["dogrulayici"]
    if "konak" in i:
        k["yonlendirilebilir"] = True
    if "durum" in i:
        sinif = i["govde"]["sinif"] if "govde" in i else i["durum"] // 100
        k["saklamaya_uygun"] = sinif == 2
        k["adres_degisti"] = sinif == 3
        if "yontem" in i:
            k["yeniden_denenebilir"] = sinif == 5 and i["yontem"] in ETKISIZ
    return k


def olc(alis: list[dict], gorunur: tuple, kararlar: tuple = KARARLAR) -> tuple:
    d = y = e = b = 0
    for x in alis:
        gercek, verilen = kahin(x), araci(ileti(x, gorunur))
        for karar in kararlar:
            if karar not in verilen:
                e += 1
            elif verilen[karar] == gercek[karar]:
                d += 1
            else:
                y += 1
        b += bayt(ileti(x, gorunur))
    return d, y, e, b


def dagilim(alis: list[dict], alan: str) -> dict:
    d: dict = {}
    for x in alis:
        d[x[alan]] = d.get(x[alan], 0) + 1
    return dict(sorted(d.items()))
```

`araci` işlevindeki tek satır bütün ayrımı taşır: gövde görünürse sınıf gövdeden, görünmezse
`durum // 100` ile satırdan okunur. İki aracı arasındaki fark yalnız budur.

## İki Aracı

```python
alis = durum_ata(alisverisler())
print("gerçek sınıf dağılımı:", dagilim(alis, "gercek_sinif"))
print("bildirilen kod dağılımı:", dagilim(alis, "durum"))
print("sınıfını yanlış bildiren yanıt:", sum(x["yanilti"] for x in alis))
t = olc(alis, SATIR, TEMEL)
print(f"temel beş karar (iki rejimde de aynı): doğru {t[0]}, yanlış {t[1]}")
print()
print(f"{'rejim':<12s} {'doğru':>6s} {'yanlış':>7s} {'alınamayan':>11s} {'bayt':>6s}")
for ad, g in (("satır", SATIR), ("satır+gövde", SATIR_GOVDE)):
    d, y, e, b = olc(alis, g)
    print(f"{ad:<12s} {d:6d} {y:7d} {e:11d} {b:6d}")
```

```
gerçek sınıf dağılımı: {2: 22, 3: 3, 4: 7, 5: 8}
bildirilen kod dağılımı: {200: 16, 201: 5, 204: 4, 301: 3, 400: 4, 404: 3, 500: 1, 503: 4}
sınıfını yanlış bildiren yanıt: 3
temel beş karar (iki rejimde de aynı): doğru 195, yanlış 5

rejim         doğru  yanlış  alınamayan   bayt
satır           309      11           0   4004
satır+gövde     315       5           0   8044
```

İlk okunacak sütun **alınamayan**dır ve iki rejimde de sıfırdır. Durum satırı görünür
olduğu sürece aracı üç yeni kararın üçünü de alır; sunucuya sormaz, tur borçlanmaz. Önceki
dersin beş kararı da yerinde durur: iki rejimde de 195 doğru, 5 yanlış.

Aradaki bütün fark üç yüz yirmi kararın **altısındadır**. Satır rejimi 309, gövdeyi de açan
rejim 315 doğru karar verir. Buna karşılık gövdeyi açmak baytı 4004'ten 8044'e çıkarır.

## Gövdenin Kazandırdığı

Altı kararın nereden geldiğine bakmak gerekir.

```python
print(f"{'':<20s} {'satır':>14s} {'satır+gövde':>16s}")
print(f"{'karar':<20s} {'doğru':>6s} {'yanlış':>7s} {'doğru':>8s} {'yanlış':>7s}")
for karar in DURUM_KARARLARI:
    s = [0, 0, 0, 0]
    for x in alis:
        gercek = kahin(x)
        for j, g in enumerate((SATIR, SATIR_GOVDE)):
            v = araci(ileti(x, g))
            s[2 * j + (0 if v[karar] == gercek[karar] else 1)] += 1
    print(f"{karar:<20s} {s[0]:6d} {s[1]:7d} {s[2]:8d} {s[3]:7d}")

print()
print(f"{'no':>3s} {'yöntem':<7s} {'yol':<14s} {'gerçek':>7s} {'bildirilen':>11s} "
      f"{'etkisiz':>8s}")
for x in alis:
    if x["yanilti"]:
        print(f"{x['no']:3d} {x['yontem']:<7s} {x['yol']:<14s} {x['gercek_sinif']:7d} "
              f"{x['durum']:11d} {str(x['yontem'] in ETKISIZ):>8s}")

ds, dg = olc(alis, SATIR), olc(alis, SATIR_GOVDE)
kazanc, bedel = dg[0] - ds[0], dg[3] - ds[3]
print()
print(f"gövdenin kazandırdığı karar {kazanc}, ödettiği bayt {bedel}, "
      f"karar başına {bedel / kazanc:.1f} bayt")
print("karar kümesi iki rejimde ayrılan alışveriş:",
      sum(1 for x in alis if araci(ileti(x, SATIR)) != araci(ileti(x, SATIR_GOVDE))))

eklenen = sum(x["gercek_sinif"] == 3 for x in alis)
kacinilan = sum(x["gercek_sinif"] == 4 for x in alis)
print(f"yönlendirmenin eklediği tur {eklenen}, boşuna denemeden kaçınılan tur "
      f"{kacinilan}, kırk alışverişte net {eklenen - kacinilan}")
```

```
                              satır      satır+gövde
karar                 doğru  yanlış    doğru  yanlış
saklamaya_uygun          37       3       40       0
adres_degisti            40       0       40       0
yeniden_denenebilir      37       3       40       0

 no yöntem  yol             gerçek  bildirilen  etkisiz
  2 PUT     /olcum/yamac         5         200     True
  8 GET     /olcum/kuzey         5         200     True
  9 GET     /ozet                5         200     True

gövdenin kazandırdığı karar 6, ödettiği bayt 4040, karar başına 673.3 bayt
karar kümesi iki rejimde ayrılan alışveriş: 3
yönlendirmenin eklediği tur 3, boşuna denemeden kaçınılan tur 7, kırk alışverişte net -4
```

Kırk alışverişin **otuz yedisinde** iki aracı aynı karar kümesini üretir. Gövdeyi açmak bu
otuz yedide tek bir kararı bile değiştirmez; yalnız bayt okur. Ayrılan üç alışverişte
kazanılan karar sayısı altı, ödenen bayt 4040 — karar başına 673,3 bayt.

Karşılaştırma ölçüsü de burada belirir. Durum satırı, aracıya kırk alışverişin kırkında üç
kararı birden verir ve bunun için alışveriş başına yalnız on iki bayt okutur. Gövde, üç yüz
yirmi kararın **altısını** düzeltir ve bunun için alışveriş başına yüz bir bayt daha okutur.
Sınıfın ilk basamağa konması bir yer kazanma tercihi değildir; aracının okuması gereken en
küçük veriyi yanıtın en başına koyma tercihidir.

## Karar Bedava, İşlem Bir Tur

`adres_degisti` kararı iki rejimde de kırk kararın kırkında doğrudur; dersin en ucuz kararı
budur. Ucuzluk, kararın **sonucunun** da ucuz olduğu anlamına gelmez.

Üçüncü sınıf bir yanıt istenen içeriği vermez, yalnız başka bir adres bildirir. Aracı bunu
iletiden okur ve kimseye sormaz — karar fazladan tur istemez. Ama kararın gereğini yapmak,
yani yeni adrese gitmek, tam bir gidiş–dönüştür. Kırk alışverişin **üçü** üçüncü
sınıftandır ve bu üç alışveriş hiçbir başlık alanının kaldıramayacağı üç tur ekler; turu
kaldırmanın tek yolu adresi değiştirmektir.

Dördüncü sınıf ters yönde çalışır. Aracı bir 4xx gördüğünde aynı isteğin yeniden
gönderilmesinin aynı sonucu vereceğini bilir ve göndermez. Kırk alışverişin **yedisi**
dördüncü sınıftandır; bu yedi alışverişte tek bir basamak, sonucu değişmeyecek bir turu
peşinen atmaktan kurtarır. Kırk alışverişteki bilanço **eksi dörttür**: yönlendirme üç tur
ekler, istemci hatası yedi turu siler.

Beşinci sınıfın bilançosu yönteme bağlıdır ve bu yüzden tek başına yazılamaz. Sekiz
alışverişin kaçının yeniden denenebileceğini belirleyen şey durum sınıfı değil, önceki
dersin ölçtüğü yöntem alanıdır; karar iki alanın kesişiminde durur.

Bu üç satır, ölçünün neden alan sayısı değil tur olduğunu gösterir. Durum satırı tek bir
alandır ve gövdeye hiç dokunmadan kırk alışverişte üç tur ekler, yedi tur siler.

## Sınıfını Yanlış Bildiren Yanıt

Üç alışverişte sunucu, sunucu tarafında oluşan bir hatayı 200 diye bildirmiştir. Gövdede
gerçek durum yazılıdır; satırda yazmaz.

Satır rejiminde bu üç yanıt iki kararı birden bozar. `saklamaya_uygun` üçünde de yanlış
çıkar: aracı başarısız bir yanıtı önbelleğine koyar ve aynı hatayı sonraki isteklere de
dağıtır. `yeniden_denenebilir` de üçünde yanlış çıkar, çünkü üçünün de yöntemi etkisizdir
ve gerçek sınıfı bilinseydi istek yeniden gönderilebilirdi. `adres_degisti` bozulmaz: yanlış
bildirim üçüncü sınıfa dokunmaz.

Buradaki asıl sonuç şudur: **aracı yanlış karar vermedi, yanlış bildirime doğru davrandı.**
İlk basamağı okumak, ilk basamağın doğru yazıldığı varsayımıyla birlikte gelir. Protokolde
bu varsayımı sınayan bir düzenek yoktur; gövdeyi açmak da bir çözüm değildir, çünkü gövdeyi
yazan da aynı sunucudur.

Daraltma tarafı da vardır. Sunucu durum satırını doğru yazdığında aracı hiçbir şey
kaybetmez; yanlış yazdığında ise kaybı gövdeyle kapatmak alışveriş başına yüz bayttan fazla
tutar ve kırk alışverişin otuz yedisinde bu bayt boşa gider. Sınıfı doğru bildirmek,
aracının okuması gereken veriyi en aza indiren tek şeydir.

## Özet

- Durum satırının ilk basamağı bir durum sınıfı verir; aracı saklama, yönlendirme ve yeniden
  deneme kararlarını kodun tamamından değil bu tek basamaktan çıkarır.
- Sınıf tabanlı okuma, aracının kodun ayrıntısını bilmesini gerektirmez: 400 ile 404 aynı
  yönergeyi taşır.
- Kırk alışveriş ve sekiz kararlık kümede satır rejimi 309 doğru, 11 yanlış karar ve 4004
  bayt; gövdeyi de açan rejim 315 doğru, 5 yanlış karar ve 8044 bayt verir.
- İki rejim kırk alışverişin otuz yedisinde aynı karar kümesini üretir; gövdenin kazandırdığı
  altı kararın bedeli karar başına 673,3 bayttır.
- Kararın ucuz olması işlemin de ucuz olduğunu göstermez: yönlendirme kırk alışverişte üç
  tur ekler, istemci hatası yedi turu siler, bilanço eksi dörttür.
- Sınıfını yanlış bildiren üç yanıt `saklamaya_uygun` ve `yeniden_denenebilir` kararlarını
  bozar; aracı yanlış karar vermez, yanlış bildirime doğru davranır.

## Sonraki Adım

Durum satırı yanıtın **ne olduğunu** söyler. Söylemediği bir şey vardır: aynı adresin
birden çok karşılığı olabilir ve sunucu bunlardan hangisini gönderdiğini durum satırında
bildirmez. Aynı ölçüm kaydı ayrı biçimlerde, ayrı dillerde, ayrı kodlamalarda sunulabilir;
ikisi de 200 ile döner. Sonraki ders bu seçimin yapıldığı yeri, yani başlık alanlarını ölçer
ve iki soruyu birden sorar: ilgisiz alanlar eklemek aracıya karar kazandırır mı, ve seçimin
hangi alana bakılarak yapıldığı bildirilmezse aracı hangi kopyayı kime verir.
