---
title: 'Yapılandırma Yönetimi'
source: 'https://academia.sh/tr/kurslar/sunucu-temelleri/yapilandirma-yonetimi'
course: 'Sunucu Tarafı Temelleri'
language: tr
updated: '2026-08-17T18:06:52+00:00'
license: 'CC BY-SA 4.0'
---

# Yapılandırma Yönetimi

Ortam değişkenlerinden okunan yapılandırma bir şemayla tanımlanır; tip, aralık ve seçenek doğrulaması açılışta yapılır, bütün sorunlar tek seferde bildirilir ve geçersiz ortamda uygulamanın sysexits çıkış koduyla düşmesi ölçülür.

Önceki ders iskeletin katmanlarını ayırdı, ama bütün değerler kodun içinde yazılı kaldı:
bağlantı noktası, ödünç günü, üye ödünç sınırı, deponun yeri. Aynı uygulama yerelde, sınama
ortamında ve yayında farklı değerlerle çalışmalıdır; bu değerler kodda durduğu sürece her
ortam için ayrı bir yapı üretmek gerekir.

Bu ders değerleri koddan çıkarıp **ortam değişkenlerine** taşır. Asıl konu değerlerin nereden
okunduğu değil, ne zaman ve nasıl doğrulandığıdır: eksik ya da yanlış tipte bir değişkenle
başlatılan uygulama ne yapmalıdır?

## Neyin Yapılandırma Olduğu

Kodda duran her sabit yapılandırma değildir. Ayrımı veren ölçüt tektir: **ortamdan ortama
değişen değer yapılandırmadır.** Ödünç süresinin on dört gün olması kütüphanenin kuralıdır ve
yayında da yerelde de aynıdır; bağlantı noktası ise makineden makineye değişir.

Bu ölçüt uygulandığında üç öbek oluşur:

- **Ortama bağlı değerler.** Bağlantı noktası, deponun adresi, kütük düzeyi, bakım kipi.
  Bunlar ortam değişkenidir.
- **İş kuralı sabitleri.** Ödünç süresi, üye ödünç sınırı. Bunlar alan katmanına aittir ve
  koddadır — ama ortamlar arasında ayarlanabilmeleri isteniyorsa yapılandırmaya geçerler.
- **Gizli değerler.** Veritabanı parolası, imzalama anahtarı. Bunlar da ortamdan gelir, ama
  ayrı bir sınıfı vardır ve sonraki dersin konusudur.

Aşağıdaki şema ilk iki öbeği bir arada tanımlar; ödünç süresi ve üye sınırı, ortamlar arası
denemeye açık olsunlar diye yapılandırmaya alınmıştır ve varsayılanları iş kuralının kendisidir.

## Şema, Varsayılan ve Doğrulama

Bir yapılandırma okuyucusunun üç işi vardır: değeri okumak, tipini doğrulamak, eksikse
varsayılanı koymak. Aşağıdaki modül bunları bir şema üzerinden yapar. Ortam değişkenleri tek
bir önek taşır; bu önek, uygulamaya ait olmayan değişkenlerin şemaya karışmasını önler.

```js
// kaynak/kurulum/yapilandirma.mjs — ortamdan okur, tumunu dogrular, degistirilemez nesne dondurur
const ONEK = "KUTUPHANE_";

export const SEMA = {
  BAGLANTI_NOKTASI: { tip: "sayi", varsayilan: 8435, alt: 1024, ust: 65535 },
  ODUNC_GUN: { tip: "sayi", varsayilan: 14, alt: 1, ust: 90 },
  UYE_ODUNC_SINIRI: { tip: "sayi", varsayilan: 5, alt: 1, ust: 50 },
  DEPO_ADRESI: { tip: "metin", zorunlu: true },
  KUTUK_DUZEYI: { tip: "secenek", secenekler: ["hata", "uyari", "bilgi", "ayrintili"],
    varsayilan: "bilgi" },
  BAKIM_KIPI: { tip: "mantiksal", varsayilan: false },
};

const cevir = (ad, kural, ham) => {
  if (kural.tip === "sayi") {
    const sayi = Number(ham);
    if (!Number.isInteger(sayi)) return { hata: `tam sayi bekleniyor, "${ham}" verildi` };
    if (sayi < kural.alt || sayi > kural.ust) {
      return { hata: `${kural.alt}-${kural.ust} araliginda olmali, ${sayi} verildi` };
    }
    return { deger: sayi };
  }
  if (kural.tip === "mantiksal") {
    if (ham !== "true" && ham !== "false") {
      return { hata: `"true" ya da "false" bekleniyor, "${ham}" verildi` };
    }
    return { deger: ham === "true" };
  }
  if (kural.tip === "secenek") {
    if (!kural.secenekler.includes(ham)) {
      return { hata: `secenekler [${kural.secenekler.join(", ")}], "${ham}" verildi` };
    }
    return { deger: ham };
  }
  return ham.length > 0 ? { deger: ham } : { hata: "bos olamaz" };
};

export const yapilandirmayiOku = (ortam) => {
  const sorunlar = [];
  const ayarlar = {};

  for (const [ad, kural] of Object.entries(SEMA)) {
    const anahtar = ONEK + ad;
    const ham = ortam[anahtar];
    if (ham === undefined) {
      if (kural.zorunlu) sorunlar.push(`${anahtar}: zorunlu, tanimli degil`);
      else ayarlar[ad] = kural.varsayilan;
      continue;
    }
    const sonuc = cevir(ad, kural, ham);
    if (sonuc.hata) sorunlar.push(`${anahtar}: ${sonuc.hata}`);
    else ayarlar[ad] = sonuc.deger;
  }

  for (const anahtar of Object.keys(ortam)) {          // yazim hatalari sessizce gecmesin
    if (anahtar.startsWith(ONEK) && !(anahtar.slice(ONEK.length) in SEMA)) {
      sorunlar.push(`${anahtar}: bilinmeyen anahtar`);
    }
  }

  if (sorunlar.length > 0) {
    const hata = new Error("yapilandirma gecersiz");
    hata.sorunlar = sorunlar.sort();
    throw hata;
  }
  return Object.freeze(ayarlar);
};
```

Üç tasarım kararı burada gizlidir ve üçü de ölçümde görünecektir.

**Bütün sorunlar toplanır.** Okuyucu ilk hatada durmaz; şemanın tamamını gezer, sorunları bir
listede biriktirir ve sonunda tek seferde bildirir. Sekiz değişkeni yanlış olan bir ortamı
sekiz kez başlatmak zorunda kalmamanın yolu budur.

**Bilinmeyen anahtar hatadır.** Önekli ama şemada karşılığı olmayan bir değişken, neredeyse
her zaman bir yazım hatasıdır. Sessizce yok sayıldığında uygulama açılır, varsayılanla çalışır
ve yanlış davranışın nedeni ortam dosyasında saatlerce aranır.

**Sonuç dondurulur.** `Object.freeze` çağrısı yapılandırmayı **değiştirilemez** hâle getirir.
Çalışma sırasında bir ayarı değiştiren kod, sürecin hangi anda hangi değerle çalıştığını
belirsizleştirir; dondurma bu yolu kapatır.

## Açılışta Düşmek

Doğrulamanın değerini belirleyen, ne zaman yapıldığıdır. Yapılandırma isteği karşılarken
okunursa hata ilk istekte, belki de yayından saatler sonra ortaya çıkar. Açılışta okunursa
hatalı ortam hiç hizmet vermez.

Aşağıdaki açılış dosyası bunu uygular: yapılandırma sunucu kurulmadan **önce** okunur,
geçersizse sunucu hiç oluşturulmaz.

```js
// kaynak/kurulum/ac.mjs — acilis: yapilandirma once okunur; gecersizse sunucu hic kurulmaz
import { createServer } from "node:http";
import { yapilandirmayiOku } from "./yapilandirma.mjs";

const EX_CONFIG = 78;                       // sysexits.h: yapilandirma hatasi

let ayar;
try {
  ayar = yapilandirmayiOku(process.env);
} catch (hata) {
  console.error(hata.message + ":");
  for (const sorun of hata.sorunlar ?? []) console.error("  - " + sorun);
  process.exit(EX_CONFIG);
}

console.log("yapilandirma: " + JSON.stringify(ayar));

try {
  ayar.ODUNC_GUN = 30;                      // degistirilemez nesne: yazma denemesi
} catch (hata) {
  console.log("ayar degistirme denemesi: " + hata.constructor.name);
}

createServer((istek, yanit) => {
  yanit.sendDate = false;
  yanit.writeHead(200, { "content-type": "application/json; charset=utf-8" });
  yanit.end(JSON.stringify({ oduncGun: ayar.ODUNC_GUN, bakim: ayar.BAKIM_KIPI }));
}).listen(ayar.BAGLANTI_NOKTASI, "127.0.0.1",
  () => console.log(`acildi 127.0.0.1:${ayar.BAGLANTI_NOKTASI}`));
```

Çıkış kodu rastgele seçilmemiştir. `sysexits.h` başlığında tanımlı `EX_CONFIG` değeri
`78`'dir ve "yapılandırma hatası" anlamına gelir. Uygulamayı gözeten bir denetçi bu kodu
gördüğünde süreci yeniden başlatmanın işe yaramayacağını bilir; aynı ortam aynı hatayı
üretecektir.

Ölçüm dört ortamla açılışı dener. `env -i` çağrısı ortamı boşaltır, böylece kabuktaki var
olan değişkenler sonuca karışmaz.

```bash
#!/usr/bin/env bash
# Dort ayri ortamla acilisi dener; her denemede iletiyi ve cikis kodunu basar.
dene() {  # $1 = aciklama, kalan argumanlar ANAHTAR=deger ciftleri
  aciklama="$1"; shift
  echo "=== $aciklama ==="
  env -i PATH="$PATH" "$@" node kaynak/kurulum/ac.mjs & pid=$!
  sleep 0.8
  if kill -0 "$pid" 2>/dev/null; then
    curl -sS "http://127.0.0.1:8435/"; echo
    kill "$pid"; echo "surec ayakta, sonlandirildi"
  else
    wait "$pid"; echo "cikis kodu=$?"
  fi
}

dene "1. zorunlu degisken eksik"
dene "2. tip ve secenek hatasi bir arada" \
  KUTUPHANE_DEPO_ADRESI=file:./veri/kutuphane.db \
  KUTUPHANE_BAGLANTI_NOKTASI=seksen \
  KUTUPHANE_KUTUK_DUZEYI=detayli \
  KUTUPHANE_ODUC_GUN=14
dene "3. aralik disi deger" \
  KUTUPHANE_DEPO_ADRESI=file:./veri/kutuphane.db \
  KUTUPHANE_BAGLANTI_NOKTASI=80
dene "4. gecerli ortam (varsayilanlar tamamliyor)" \
  KUTUPHANE_DEPO_ADRESI=file:./veri/kutuphane.db \
  KUTUPHANE_BAKIM_KIPI=true
```

```
=== 1. zorunlu degisken eksik ===
yapilandirma gecersiz:
  - KUTUPHANE_DEPO_ADRESI: zorunlu, tanimli degil
cikis kodu=78
=== 2. tip ve secenek hatasi bir arada ===
yapilandirma gecersiz:
  - KUTUPHANE_BAGLANTI_NOKTASI: tam sayi bekleniyor, "seksen" verildi
  - KUTUPHANE_KUTUK_DUZEYI: secenekler [hata, uyari, bilgi, ayrintili], "detayli" verildi
  - KUTUPHANE_ODUC_GUN: bilinmeyen anahtar
cikis kodu=78
=== 3. aralik disi deger ===
yapilandirma gecersiz:
  - KUTUPHANE_BAGLANTI_NOKTASI: 1024-65535 araliginda olmali, 80 verildi
cikis kodu=78
=== 4. gecerli ortam (varsayilanlar tamamliyor) ===
yapilandirma: {"BAGLANTI_NOKTASI":8435,"ODUNC_GUN":14,"UYE_ODUNC_SINIRI":5,"DEPO_ADRESI":"file:./veri/kutuphane.db","KUTUK_DUZEYI":"bilgi","BAKIM_KIPI":true}
ayar degistirme denemesi: TypeError
acildi 127.0.0.1:8435
{"oduncGun":14,"bakim":true}
surec ayakta, sonlandirildi
```

## Ölçümün Söyledikleri

**Birinci deneme** zorunlu bir değişkenin eksikliğini gösterir. Uygulama açılmamış, bağlantı
noktasını dinlememiş ve `78` ile çıkmıştır. Eksik olan değerin ne olduğu adıyla yazılmıştır;
"bir şeyler ters gitti" biçiminde bir ileti, ortam dosyasını düzeltecek kişiye hiçbir şey
söylemez.

**İkinci deneme** üç ayrı sorunu bir arada bildirir. `BAGLANTI_NOKTASI` sayıya çevrilememiş,
`KUTUK_DUZEYI` seçenek listesinde bulunmamış ve `KUTUPHANE_ODUC_GUN` bilinmeyen anahtar
olarak işaretlenmiştir. Üçüncüsü, `ODUNC` yerine `ODUC` yazılmış bir değişkendir; şema bunu
yakalamasa uygulama açılır ve ödünç süresi sessizce varsayılanda kalırdı. İletide seçenek
listesinin de yazılmış olması, düzeltmeyi belgeye bakmadan yapılabilir kılar.

**Üçüncü deneme** tip doğru, değer yanlış durumunu ayırır. `80` geçerli bir tam sayıdır ama
ayrıcalıklı bağlantı noktası aralığındadır. Tip denetimi tek başına yetmez; anlamlı aralık da
şemanın parçasıdır.

**Dördüncü deneme** geçerli ortamı gösterir. Yalnız iki değişken verilmiştir; kalan dördü
varsayılanlarıyla tamamlanmış ve tam yapılandırma tek satırda yazdırılmıştır. Açılışta
yapılandırmanın kütüğe yazılması, bir sürecin hangi ayarlarla çalıştığını sonradan sormaya
gerek bırakmaz.

Aynı çıktıda `ayar degistirme denemesi: TypeError` satırı, dondurulmuş nesneye yazma
girişiminin sessizce yutulmadığını doğrular. Modül kodu katı kipte çalıştığı için atama bir
hata fırlatır; katı kip dışında aynı atama sessizce yok sayılırdı.

## Öncelik Sırası ve Ortam Dosyası

Ortam değişkeni tek kaynak değildir. Node.js Çalışma Zamanı kursunun Yapılandırma Yönetimi
dersinde kurulan **katmanlı yapılandırma** düzeni burada da geçerlidir: bir değer birden çok
yerde tanımlanabilir ve hangisinin kazandığı önceden belirlenmiş olmalıdır. Yaygın sıra,
soldan sağa artan öncelikle şudur: şemadaki varsayılan, ortam dosyası, gerçek ortam
değişkeni, komut satırı seçeneği.

Bu okuyucu yalnız iki katman kullanır — varsayılan ve ortam değişkeni — ama sıra genişletmeye
açıktır: `yapilandirmayiOku` fonksiyonu ortamı parametre olarak aldığı için, çağıran taraf
katmanları birleştirip tek bir nesne verebilir. Fonksiyonun `process.env` değerini kendi
içinden okumaması bilinçli bir karardır; bu sayede sınamalarda gerçek ortam kirletilmeden
farklı ortamlar denenebilir.

Ortam dosyasının kendisi bir kolaylıktır ve sınırı vardır: yerel geliştirmede rahatlık
sağlar, yayında ise değerlerin nereden geldiğini gizler. Dosyanın sürüm denetimine
girmemesinin nedeni de budur ve bu, sonraki dersin sınırını çizer.

## Özet

- Ortamdan ortama değişen değer yapılandırmadır; değişmeyen kural koda, gizli değerler ise
  ayrı bir sınıfa aittir.
- Şema her değişkenin tipini, aralığını, seçeneklerini ve varsayılanını tek yerde tanımlar;
  okuyucu ilk hatada durmaz, bütün sorunları toplayıp tek seferde bildirir.
- Önekli ama şemada bulunmayan bir anahtar hata sayılır; ölçümde `KUTUPHANE_ODUC_GUN` yazım
  hatası bu kuralla yakalanmıştır.
- Doğrulama açılışta yapılır: geçersiz ortamda sunucu hiç kurulmaz ve süreç `sysexits.h`
  başlığındaki `EX_CONFIG` değeriyle, yani `78` ile çıkar.
- Okunan yapılandırma dondurulur; katı kipte çalışan modül kodunda değiştirme girişimi
  `TypeError` üretir. Eksik bırakılan ayarlar varsayılanlarla tamamlanır ve açılışta kütüğe
  yazılır.

## Sonraki Adım

Bu dersin şemasında bir değişken kasten yoktu: deponun parolası. Bağlantı noktası ile parola
aynı yerden, ortamdan okunur; buna karşılık biri kütüğe yazılabilir, diğeri yazılamaz. Sonraki
ders bu sınırı çizer: yapılandırma ile gizli değer arasındaki fark nedir, gizli bir değerin
kütüğe, hata yanıtına ve istemciye ulaşmasını hangi kurallar engeller ve maskelemenin
gerçekten uygulandığı nasıl denetlenir?
