Blog
Mert Özen'in yazılım geliştirme, backend, frontend ve DevOps üzerine blog yazıları.
Node.js Nedir? V8, libuv ve Event-Driven Sunucu Modeli: ASP.NET Core Geliştiricisinin Gözüyle
Node.js, JavaScript'i sunucuda V8 engine'i ve libuv event loop'u ile çalıştıran bir runtime'dır: kodun tek thread'de çalışır, I/O beklemesi thread tutmaz, ama uzun bir senkron hesaplama bütün request'leri bekletir. Gerçek ölçümlerle 500 eşzamanlı beklemenin 227 ms sürmesi, 1,4 saniyelik bir raporun basit bir isteği 1.340 ms bekletmesi, 4 thread'lik libuv pool'u, Kestrel/ThreadPool ile karşılaştırma, Node mu .NET mi tablosu ve Node 27 ile gelen yıllık release takvimi.
Node.js Kurulumu ve İlk Proje: Version Manager, .nvmrc, package.json, node --watch ve --env-file
Node.js projesine başlamanın doğru yolu Node'u bir version manager ile kurmak, sürümü .nvmrc ve package.json'daki engines alanıyla sabitlemek ve script'leri package.json'a yazmaktır. Gerçek çıktılarla engine-strict'in Node 24'te verdiği EBADENGINE hatası, npm init ve package.json anatomisi, node --watch ile yeniden başlatma, --env-file'da shell değerinin .env'i ezmesi, node --run ile npm run arasındaki 0,04 / 0,11 saniyelik fark ve Bookstore API'sinin ilk GET /health endpoint'i.
Node.js Module Sistemi: CommonJS ve ES Module, "type", "exports" ve require(esm)
Node.js bir dosyayı uzantısına (.mjs/.cjs) ve en yakın package.json'daki "type" alanına göre CommonJS ya da ES module olarak yükler; Node 26'da require(esm) stable olduğu için iki dünya artık birbirini top-level await dışında sorunsuz yükleyebiliyor. Gerçek hatalarla uzantısız import, ERR_REQUIRE_ASYNC_MODULE, CommonJS'ten named import, exports ile kapatılan yollar, dual package hazard ve Bookstore API'sinde #-alias'lar ile JSON import attribute'ları.
npm Derinlemesine: Dependency'ler, SemVer Aralıkları, package-lock, npm ci, Workspace'ler ve Supply Chain Güvenliği
npm, package.json'daki aralığı package-lock.json'a kaydettiği tam sürümle sabitler: lock aralığı karşıladığı sürece npm install yeni sürüme geçmez, npm ci ise lock'tan sapmaya hiç izin vermez. Gerçek çıktılarla ^ ve ~ aralıklarının Express sürümlerinde ne seçtiği, 0.x caret tuzağı, uyumsuz lock'ta duran npm ci, iç içe content-type kopyaları, @bookstore/contracts workspace'i, npm audit, strict-allow-scripts ile install script onayı ve imza doğrulaması.
Node.js'te TypeScript: Native Type Stripping, erasableSyntaxOnly ve Build'siz Geliştirme
Node.js 26, .ts dosyalarını tipleri boşlukla silerek build adımı olmadan çalıştırır ama tipleri kontrol etmez; bu yüzden tsc --noEmit ayrı ve zorunlu bir adım olmalıdır. Gerçek çıktılarla tip hatalı bir dosyanın 699.8 yazdırması, enum ve parameter property hataları, import type zorunluluğu, Node'un önerdiği tsconfig, Bookstore API'sinin TypeScript 7'ye geçişi, paths yerine imports, node_modules'taki .ts yasağı ve build'in yine gerektiği durumlar.
Node.js Event Loop'u Sunucu Tarafında: libuv Phase'leri, process.nextTick, setImmediate ve Event Loop'u Bloklamak
Node.js event loop'u her turda libuv phase'lerinden (pending, poll, check, close, timers) geçer ve her callback'ten sonra önce nextTick, sonra promise queue'sunu boşaltır; bu yüzden I/O callback'i içinde setImmediate, setTimeout(0)'dan önce çalışır. Gerçek ölçümlerle dolu thread pool'un dosya okumayı 371 ms bekletmesi, JSON.parse ve ReDoS ile bloklama, monitorEventLoopDelay ve Bookstore fiyat raporunun inline, parçalı ve worker modlarında /health'i 481, 13 ve 1 ms bekletmesi.
Node.js'te Asenkron Pattern'ler: Callback'ten Promise'e, EventEmitter, AbortSignal ve AsyncLocalStorage
Node.js'te asenkron kodun temel parçaları promise API'leri, senkron çalışan EventEmitter, iptal için AbortSignal ve request bağlamını await'ler boyunca taşıyan AsyncLocalStorage'dır. Gerçek çıktılarla emit'in listener'ları senkron çağırması, dinlenmeyen 'error' ile çöken process, captureRejections, AbortSignal.timeout ve any(), global değişkenle karışan request id'leri ve Bookstore'da orderPlaced event'i yayan OrderService.
Node.js'te File System: fs/promises, path, Buffer ve Dosya İşlemlerinde Tuzaklar
Node.js sunucusunda dosya işlemleri node:fs/promises ile yapılır; ama asıl iş encoding'i doğru ele almak, dosyayı atomik yazmak ve kullanıcıdan gelen yolu kök klasöre hapsetmektir. Gerçek çıktılarla 8 karakterlik Çalıkuşu'nun 11 byte olması, chunk sınırında bozulan Türkçe karakterler, Excel CSV'sindeki BOM, writeFile ile 62 okumanın 61'inin yarım dosya görmesi, kaybolan güncellemeler, startsWith tuzağı ve Permission Model'in fsync'i kapatması.
Node.js Stream'leri: Readable, Writable, Transform, pipeline() ve Backpressure
Node.js stream'leri veriyi parça parça işler; write() false döndüğünde drain'i beklemek, yani backpressure'a uymak belleği sabit tutar ve pipeline() bunu hata yönetimiyle birlikte her aşamaya bağlar. Gerçek ölçümlerle false'u yok sayan producer'ın heap'i 182 MB'a çıkarması, pipe()'ın kaynak dosyayı açık bırakması, 505 MB'lık Bookstore sipariş export'unun 147 MB RSS ile stream edilmesi ve aynı işin bellekte 993 MB tutması.
node:http ile Çıplak HTTP Server: Request/Response, Routing'i Elle Yazmak ve Neden Framework Gerekir
node:http, Node'da HTTP'nin en alt katıdır: body'yi boyut limitiyle okumak, routing, validation ve hata yönetimi senin işindir; async bir handler'daki tek bir hata bile process'i kapatabilir. Gerçek çıktılarla çöken sunucu, stream olarak okunan JSON body ve 413/415/422 cevapları, elle yazılmış router, client gidince durdurulan worker, :: üzerinde dinleyen listen(), slowloris'e 408 dönen headersTimeout ve 413'ten sonra açık kalan bağlantı.
Express 5'e Giriş: Routing, Middleware Zinciri ve Express 4'ten Değişenler
Express 5, async handler'lardaki hataları kendiliğinden hata middleware'ine taşır, path syntax'ını path-to-regexp 8'e geçirir ve parse edilmemiş body için req.body'yi undefined bırakır. Gerçek çıktılarla Express 4'ün aynı hatada çökmesi, artık açılışta hata veren eski path'ler, üç parametreli hata handler tuzağı, Bookstore API'sinin Express'e taşınması, EADDRINUSE'u sessizce yutan listen ve NODE_ENV=production'ın JSON API'de hızı değiştirmemesi.
Express ile Bookstore REST API: Router'lar, zod ile Validation, Async Error Handling ve Problem Details
Express ile sağlam bir REST API, katmanları ayırır, her request'i zod şemasıyla doğrulayıp tipi şemadan türetir, hataları tek bir middleware'de RFC 9457 Problem Details'a çevirir ve parayı float değil kuruş cinsinden tam sayı tutar. Gerçek çıktılarla 1339.1999999999998 TL'lik sipariş, 20 milyon satırda 5 kuruş sapan float toplamı, altı hatayı tek cevapta dönen validation, ASP.NET Core ile aynı Problem Details sözleşmesi, sayfalama ve z.toJSONSchema.