Takip et

Node.js ve Express ile Gelişime Başlangıç Rehberi

Node.js ve Express ile Gelişime Başlangıç Rehberi Giriş: Web Geliştirmenin Kalbinde Node.js ve Express Günümüzün modern web uygulamaları,

Node.js ve Express ile Gelişime Başlangıç Rehberi

Giriş: Web Geliştirmenin Kalbinde Node.js ve Express

Günümüzün modern web uygulamaları, sadece istemci tarafında zengin kullanıcı deneyimleri sunmakla kalmıyor, aynı zamanda sunucu tarafında da yüksek performans, ölçeklenebilirlik ve esneklik bekliyor. İşte tam bu noktada Node.js ve Express ikilisi devreye giriyor. Node.js, Google Chrome’un V8 JavaScript motoru üzerine kurulu, sunucu tarafı ağ uygulamaları geliştirmek için kullanılan açık kaynaklı, çalışma zamanı bir ortamdır. Geleneksel sunucu dillerinin aksine, JavaScript’i sunucu tarafında çalıştırmanıza olanak tanır ve olay odaklı, engellemeyen (non-blocking) I/O modeli sayesinde yüksek performanslı ve ölçeklenebilir uygulamalar geliştirmek için idealdir. Express.js ise Node.js için minimalist ve esnek bir web uygulama çatısıdır (framework). Node.js’in ham gücünü kullanarak web uygulamaları ve API’ler oluşturmayı çok daha kolay ve düzenli hale getirir. Bu makalede, Node.js ve Express dünyasına adım atacak, kurulumdan başlayarak temel kavramları öğrenecek, basit bir REST API geliştirecek ve bu güçlü ikiliyle neler yapabileceğinizi keşfedeceksiniz.

Node.js Kurulumu: İlk Adımlarınızı Atın

Node.js ve Express ile çalışmaya başlamak için öncelikle Node.js’i geliştirme ortamınıza kurmanız gerekir. Bu bölüm, farklı işletim sistemlerinde Node.js kurulumunu ve kurulumun doğrulanmasını kapsayacaktır.

İşletim Sistemlerine Göre Kurulum

* Windows:
Node.js’in resmi web sitesi (nodejs.org) üzerinden Windows Installer (.msi) dosyasını indirmeniz en kolay yoldur. İndirdiğiniz dosyayı çalıştırın ve kurulum sihirbazındaki adımları takip edin. Varsayılan ayarlarla ilerlemek genellikle yeterlidir. Bu kurulum, Node.js ile birlikte npm (Node Package Manager) paket yöneticisini de otomatik olarak yükleyecektir.
* macOS:
Windows’a benzer şekilde, Node.js’in resmi web sitesinden macOS Installer (.pkg) dosyasını indirip kurabilirsiniz. Alternatif olarak, macOS kullanıcıları genellikle Homebrew paket yöneticisini tercih ederler. Homebrew kurulu ise, terminalde aşağıdaki komutu çalıştırarak Node.js’i kurabilirsiniz:

brew install node

Bu komut, Node.js ve npm’i sisteminize kuracaktır.
* Linux (Ubuntu/Debian tabanlı sistemler için örnek):
Linux dağıtımları için Node.js’i kurmanın birkaç yolu vardır. En yaygın yöntemlerden biri, NodeSource depolarını kullanmaktır. Bu depolar, Node.js’in en güncel ve kararlı sürümlerini sunar.

curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
    sudo apt-get install -y nodejs

lts.x yerine istediğiniz Node.js versiyonunu (örneğin 18.x, 20.x) yazabilirsiniz. Bu işlem de npm’i otomatik olarak kuracaktır.

Kurulum Doğrulaması

Kurulum tamamlandıktan sonra, Node.js ve npm’in doğru bir şekilde kurulup kurulmadığını kontrol etmek önemlidir. Terminalinizi veya komut istemcinizi açın ve aşağıdaki komutları çalıştırın:

node -v
npm -v

Bu komutlar, kurulu Node.js ve npm’in versiyon numaralarını döndürmelidir. Eğer versiyon numaralarını görüyorsanız, kurulum başarılı demektir.

Versiyon Yöneticileri (NVM – Node Version Manager)

Geliştirme sürecinde farklı Node.js projeleriyle çalışırken, her projenin farklı bir Node.js versiyonu gerektirdiğini fark edebilirsiniz. Bu durumu yönetmek için NVM (Node Version Manager) gibi araçlar oldukça kullanışlıdır. NVM, tek bir sistemde birden fazla Node.js versiyonunu kurmanıza, bunlar arasında kolayca geçiş yapmanıza ve varsayılan versiyonu ayarlamanıza olanak tanır.
NVM’i kurmak için resmi GitHub sayfasındaki yönergeleri takip edebilirsiniz. Kurulduktan sonra, aşağıdaki gibi komutlarla farklı Node.js versiyonlarını yönetebilirsiniz:

nvm install 18 # Node.js 18.x sürümünü kurar
nvm use 18     # Node.js 18.x sürümünü kullanır
nvm install 20 # Node.js 20.x sürümünü kurar
nvm use 20     # Node.js 20.x sürümünü kullanır
nvm ls         # Kurulu tüm Node.js versiyonlarını listeler

Temel Node.js Kavramları: JavaScript’in Gücü Sunucuda

Node.js ile etkili bir şekilde çalışmak için bazı temel kavramları anlamak kritik öneme sahiptir.

Modüller

Node.js, uygulamaları küçük, yeniden kullanılabilir parçalara bölmek için modül sistemini kullanır. Bu, kodun düzenli, okunabilir ve yönetilebilir olmasını sağlar. İki ana modül sistemi vardır:

* CommonJS (require/module.exports): Node.js’in geleneksel modül sistemidir. Bir modülü dışa aktarmak için module.exports, içe aktarmak için ise require() kullanılır.

// myModule.js
    function greet(name) {
        return Hello, ${name}!;
    }
    module.exports = greet;

    // app.js
    const greet = require('./myModule');
    console.log(greet('Node.js')); // Hello, Node.js!

* ES Modules (import/export): ECMAScript 2015 (ES6) ile standartlaşan bu modül sistemi, tarayıcılar ve Node.js tarafından giderek daha fazla benimsenmektedir. package.json dosyanızda "type": "module" tanımlayarak veya .mjs uzantılı dosyalar kullanarak ES modüllerini kullanabilirsiniz.

// myModule.mjs
    export function greet(name) {
        return Hello, ${name}!;
    }

    // app.mjs
    import { greet } from './myModule.mjs';
    console.log(greet('Node.js')); // Hello, Node.js!

npm (Node Package Manager)

npm, Node.js ekosisteminin kalbinde yer alan bir paket yöneticisidir. Milyonlarca açık kaynak kütüphane ve aracı barındıran npm kayıt defterinden paketleri indirmenizi, projenize dahil etmenizi ve kendi projelerinizi yayınlamanızı sağlar.

* npm init: Yeni bir Node.js projesi başlattığınızda, bu komutu çalıştırarak package.json dosyasını oluşturursunuz. Bu dosya, projenizin metadata’sını (adı, versiyonu, açıklaması, ana giriş noktası, bağımlılıkları vb.) tutar.
* npm install : Belirli bir paketi projenize bağımlılık olarak eklemek için kullanılır. Örneğin, npm install express.
* npm install: package.json dosyasında listelenen tüm bağımlılıkları yükler. Genellikle bir projeyi klonladıktan sonra çalıştırılır.
* npm uninstall : Bir paketi projeden kaldırır.

package.json

Bu dosya, her Node.js projesinin kimlik kartıdır. Projenin adı, versiyonu, açıklaması, ana giriş dosyası (main), çalıştırılabilir komutlar (scripts) ve en önemlisi, projenin ihtiyaç duyduğu tüm bağımlılıklar (dependencies ve devDependencies) burada tanımlanır.

{
  "name": "my-node-app",
  "version": "1.0.0",
  "description": "My first Node.js and Express application.",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "dev": "nodemon app.js"
  },
  "keywords": [],
  "author": "Your Name",
  "license": "ISC",
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.1"
  }
}

Asenkron Programlama (Callbacks, Promises, Async/Await)

Node.js’in en güçlü özelliklerinden biri, engellemeyen (non-blocking) I/O modelidir. Bu, Node.js’in bir işlem tamamlanırken diğer işlemleri yapmaya devam edebilmesi anlamına gelir. Bu model, asenkron programlama ile yönetilir.

* Callbacks: Geleneksel olarak, Node.js’te asenkron işlemleri yönetmek için callback fonksiyonları kullanılırdı. Bir işlem bittiğinde çağrılacak fonksiyonu parametre olarak geçersiniz.

fs.readFile('file.txt', 'utf8', (err, data) => {
        if (err) {
            console.error('Error reading file:', err);
            return;
        }
        console.log('File content:', data);
    });
    console.log('Reading file...'); // Bu önce çalışır

* Promises: Callback cehenneminden (callback hell) kaçınmak ve asenkron kodu daha okunabilir hale getirmek için Promises (Vaatler) ortaya çıktı. Bir işlem gelecekteki bir değeri temsil eder ve başarılı olursa .then(), başarısız olursa .catch() ile işlenir.

function readFilePromise(filePath) {
        return new Promise((resolve, reject) => {
            fs.readFile(filePath, 'utf8', (err, data) => {
                if (err) reject(err);
                else resolve(data);
            });
        });
    }

    readFilePromise('file.txt')
        .then(data => console.log('File content:', data))
        .catch(err => console.error('Error reading file:', err));

* Async/Await: ES2017 ile gelen async/await sentaksı, Promises’ın üzerine inşa edilmiştir ve asenkron kodu senkron gibi yazmanızı sağlar, bu da okunabilirliği büyük ölçüde artırır.

async function processFile() {
        try {
            const data = await readFilePromise('file.txt');
            console.log('File content:', data);
        } catch (err) {
            console.error('Error reading file:', err);
        }
    }
    processFile();

Olay Döngüsü (Event Loop)

Node.js’in engellemeyen yapısının temelinde Olay Döngüsü yatar. Tek iş parçacıklı olmasına rağmen, I/O işlemleri gibi uzun süren görevleri arka planda yürütür ve tamamlandıklarında bir callback’i olay kuyruğuna ekler. Olay döngüsü, çağrı yığını boşaldığında bu kuyruktaki callback’leri sırayla işler. Bu model, Node.js’in aynı anda binlerce bağlantıyı verimli bir şekilde yönetmesini sağlar.

Express.js’e Giriş: Web Uygulamaları Oluşturmanın Kolay Yolu

Node.js’in gücü tartışılmaz olsa da, ham Node.js ile bir web sunucusu oluşturmak ve karmaşık yönlendirme, middleware yönetimi gibi görevleri ele almak oldukça zahmetli olabilir. İşte Express.js’in parladığı yer burasıdır.

Express Nedir, Neden Kullanılır?

Express.js, Node.js için minimal ve esnek bir web uygulama çatısıdır. Web uygulamaları ve API’ler geliştirmek için güçlü bir dizi özellik sunar:
* Yönlendirme (Routing): HTTP metotlarına (GET, POST, PUT, DELETE vb.) ve URL yollarına dayalı olarak sunucu isteklerine yanıt verme mekanizması.
* Middleware: İstek ve yanıt döngüsü boyunca işlevsellik eklemenizi sağlayan ara yazılım katmanları.
* Şablon Motoru Entegrasyonu: Dinamik HTML sayfaları oluşturmak için Pug (Jade), EJS, Handlebars gibi şablon motorlarıyla kolay entegrasyon.
* Genişletilebilirlik: Binlerce üçüncü taraf npm paketi ile kolayca genişletilebilir.
* Hızlı Geliştirme: Minimalist yapısı sayesinde hızlı prototipleme ve uygulama geliştirmeye olanak tanır.

Temel Bir Express Uygulaması Oluşturma

Şimdi, ilk Express uygulamanızı oluşturalım.

1. Proje Dizini Oluşturma:

mkdir my-express-app
    cd my-express-app

2. npm init ile Projeyi Başlatma:

npm init -y

-y bayrağı, tüm sorulara varsayılan cevapları vermenizi sağlar ve hızlıca bir package.json dosyası oluşturur.

3. Express’i Kurma:

npm install express

Bu komut, express paketini indirir ve package.json dosyanızdaki dependencies bölümüne ekler.

4. “Hello World” Express Uygulaması:
app.js adında yeni bir dosya oluşturun ve aşağıdaki kodu ekleyin:

// app.js
    const express = require('express'); // Express modülünü içe aktar
    const app = express();              // Express uygulamasını başlat
    const port = 3000;                  // Uygulamanın dinleyeceği port numarası

    // Ana dizine (root URL) gelen GET isteklerini dinle
    app.get('/', (req, res) => {
      res.send('Hello World from Express!'); // İstemciye "Hello World" yanıtı gönder
    });

    // Uygulamayı belirtilen portta dinlemeye başla
    app.listen(port, () => {
      console.log(Express uygulaması http://localhost:${port} adresinde çalışıyor);
    });

Uygulamayı çalıştırmak için terminalinizde:

node app.js

Komutunu çalıştırın. Tarayıcınızda http://localhost:3000 adresine gittiğinizde “Hello World from Express!” mesajını görmelisiniz. Tebrikler, ilk Express uygulamanızı çalıştırdınız!

Express Temelleri: Middleware ve Yönlendirme

Express’in gücü, middleware ve yönlendirme mekanizmalarında yatar. Bu kavramları anlamak, karmaşık web uygulamaları geliştirmenin anahtarıdır.

Middleware Kavramı

Middleware (ara yazılım), Express uygulamasının istek-yanıt döngüsü sırasında yürütülen işlevlerdir. Bu işlevler, bir HTTP isteği sunucuya ulaştığında, yanıt gönderilmeden önce veya sonra çalışabilir. Her middleware fonksiyonu, req (istek), res (yanıt) nesnelerine ve bir sonraki middleware fonksiyonuna geçmek için next adlı bir fonksiyona erişebilir.

* Uygulama Seviyesi Middleware: app.use() ile tüm isteklere uygulanan middleware’lerdir.

app.use((req, res, next) => {
      console.log('Bir istek geldi:', req.method, req.url);
      next(); // Bir sonraki middleware'e veya rota işleyicisine geç
    });

* Yönlendirici Seviyesi Middleware: Belirli bir rota veya rota grubu için uygulanan middleware’lerdir.

app.get('/users', (req, res, next) => {
      console.log('Kullanıcılar rotasına istek geldi.');
      next();
    }, (req, res) => {
      res.send('Kullanıcı listesi');
    });

* Hata İşleme Middleware: Dört argüman alan özel bir middleware türüdür: (err, req, res, next). Uygulamada bir hata oluştuğunda tetiklenir. Her zaman diğer app.use() çağrılarından sonra tanımlanmalıdır.

app.use((err, req, res, next) => {
      console.error(err.stack);
      res.status(500).send('Sunucu Hatası!');
    });

* Yerleşik Middleware: Express’in kendi içinde gelen ve sıklıkla kullanılan middleware’lerdir.
* express.static('public'): Statik dosyaları (HTML, CSS, JavaScript, resimler) sunmak için kullanılır.
* express.json(): Gelen istek gövdesindeki JSON verilerini ayrıştırmak için kullanılır.
* express.urlencoded({ extended: true }): Gelen istek gövdesindeki URL kodlu verileri (form verileri gibi) ayrıştırmak için kullanılır.
* Üçüncü Taraf Middleware: npm üzerinden kurulan ve yaygın olarak kullanılan middleware’lerdir.
* morgan: HTTP isteklerini loglamak için kullanılır. npm install morgan ile kurulur.
* body-parser: Gelen istek gövdesini ayrıştırmak için kullanılır (Express 4.16.0’dan itibaren express.json() ve express.urlencoded() ile entegre edilmiştir, bu yüzden genellikle ayrı olarak kurulmasına gerek kalmamıştır).

Yönlendirme (Routing)

Yönlendirme, bir uygulamanın istemci isteklerine nasıl yanıt verdiğini tanımlar. Belirli bir URL yoluna ve HTTP metoduna (GET, POST, PUT, DELETE vb.) göre farklı işlevsellikler tetikleyebilirsiniz.

* HTTP Metotları:

app.get('/api/data', (req, res) => {
      res.json({ message: 'GET isteği' });
    });

    app.post('/api/data', (req, res) => {
      res.json({ message: 'POST isteği', data: req.body });
    });

    app.put('/api/data/:id', (req, res) => {
      res.json({ message: PUT isteği, ID: ${req.params.id} });
    });

    app.delete('/api/data/:id', (req, res) => {
      res.json({ message: DELETE isteği, ID: ${req.params.id} });
    });

* Rota Parametreleri (/users/:id): URL’deki dinamik segmentleri yakalamak için kullanılır. req.params nesnesinde erişilebilir.

app.get('/users/:userId/books/:bookId', (req, res) => {
      console.log(req.params.userId); // 'req.params.userId' değerini verir
      console.log(req.params.bookId); // 'req.params.bookId' değerini verir
      res.send(Kullanıcı ID: ${req.params.userId}, Kitap ID: ${req.params.bookId});
    });

* Sorgu Parametreleri (/search?q=node): URL’deki sorgu dizesi parametrelerini yakalamak için kullanılır. req.query nesnesinde erişilebilir.

app.get('/search', (req, res) => {
      const searchTerm = req.query.q;
      const category = req.query.category;
      res.send(Arama terimi: ${searchTerm}, Kategori: ${category});
    });
    // Örnek: /search?q=express&category=web

* Router Sınıfı: Büyük uygulamalarda yönlendirmeyi daha modüler hale getirmek için express.Router() sınıfı kullanılır. Bu, rotaları ayrı dosyalarda tanımlamanıza ve ana uygulamaya eklemenize olanak tanır.

// routes/userRoutes.js
    const express = require('express');
    const router = express.Router();

    router.get('/', (req, res) => {
      res.send('Tüm kullanıcılar');
    });

    router.get('/:id', (req, res) => {
      res.send(Kullanıcı ID: ${req.params.id});
    });

    module.exports = router;

    // app.js
    const userRoutes = require('./routes/userRoutes');
    app.use('/users', userRoutes); // '/users' ön eki ile userRoutes'ı kullan

İstek (Request) ve Yanıt (Response) Nesneleri

Express’teki her rota işleyici fonksiyonu, iki ana nesne alır: req (request – istek) ve res (response – yanıt).

* req Nesnesi: İstemciden gelen HTTP isteği hakkında bilgiler içerir.
* req.params: Rota parametreleri (/users/:id durumunda id).
* req.query: URL sorgu parametreleri (/search?q=node durumunda q).
* req.body: POST/PUT isteklerinde gönderilen veri (JSON, form verileri vb.). Bu verilere erişmek için express.json() veya express.urlencoded() middleware’leri gereklidir.
* req.headers: İstek başlıkları.
* req.method: İstek metodu (GET, POST vb.).
* req.url: İstek URL’si.
* res Nesnesi: Sunucunun istemciye göndereceği HTTP yanıtını oluşturmak için kullanılır.
* res.send(body): Çeşitli türlerde yanıtlar göndermek için kullanılır (string, buffer, object, array). Content-Type başlığını otomatik ayarlar.
* res.json(obj): JSON formatında yanıt göndermek için kullanılır. res.send()‘in JSON versiyonudur.
* res.status(code): HTTP durum kodunu ayarlar (örn. res.status(404).send('Bulunamadı')).
* res.render(viewName, data): Şablon motoru kullanarak dinamik HTML sayfaları oluşturmak ve göndermek için kullanılır.
* res.redirect(url): İstemciyi başka bir URL’ye yönlendirir.

Gerçek Bir Uygulama Örneği: Basit Bir REST API Oluşturma

Şimdi öğrendiklerimizi birleştirerek, basit bir “Görev Yönetimi” REST API’si oluşturalım. Bu API, görevleri (task) oluşturma, okuma, güncelleme ve silme (CRUD) işlemlerini destekleyecek. Veritabanı yerine basit bir bellek içi dizi kullanacağız.

1. Proje Yapısı:

my-task-api/
    ├── node_modules/
    ├── package.json
    ├── app.js
    └── tasks.js (veri depolama)

2. app.js dosyasını güncelleyin:

const express = require('express');
    const app = express();
    const port = 3000;

    // Middleware'ler
    app.use(express.json()); // JSON istek gövdelerini ayrıştırmak için
    app.use(express.urlencoded({ extended: true })); // URL-encoded istek gövdelerini ayrıştırmak için

    // Görevlerimizi depolayacağımız basit bir dizi (veri tabanı yerine)
    let tasks = [
      { id: 1, title: 'Node.js Öğren', completed: false },
      { id: 2, title: 'Express.js İncele', completed: true },
    ];
    let nextId = 3; // Yeni görevler için ID üretici

    // --- CRUD Operasyonları ---

    // 1. Tüm Görevleri Getir (GET /tasks)
    app.get('/tasks', (req, res) => {
      res.json(tasks);
    });

    // 2. Belirli Bir Görevi Getir (GET /tasks/:id)
    app.get('/tasks/:id', (req, res) => {
      const taskId = parseInt(req.params.id);
      const task = tasks.find(t => t.id === taskId);

      if (!task) {
        return res.status(404).json({ message: 'Görev bulunamadı' });
      }
      res.json(task);
    });

    // 3. Yeni Bir Görev Oluştur (POST /tasks)
    app.post('/tasks', (req, res) => {
      const { title, completed } = req.body;

      if (!title) {
        return res.status(400).json({ message: 'Başlık alanı zorunludur' });
      }

      const newTask = {
        id: nextId++,
        title,
        completed: completed || false, // Varsayılan olarak false
      };
      tasks.push(newTask);
      res.status(201).json(newTask); // 201 Created durumu ile yeni görevi döndür
    });

    // 4. Bir Görevi Güncelle (PUT /tasks/:id)
    app.put('/tasks/:id', (req, res) => {
      const taskId = parseInt(req.params.id);
      const { title, completed } = req.body;

      const taskIndex = tasks.findIndex(t => t.id === taskId);

      if (taskIndex === -1) {
        return res.status(404).json({ message: 'Görev bulunamadı' });
      }

      if (!title && completed === undefined) {
          return res.status(400).json({ message: 'Güncellenecek veri sağlanmadı' });
      }

      // Mevcut görevi güncelle
      if (title) tasks[taskIndex].title = title;
      if (completed !== undefined) tasks[taskIndex].completed = completed;

      res.json(tasks[taskIndex]);
    });

    // 5. Bir Görevi Sil (DELETE /tasks/:id)
    app.delete('/tasks/:id', (req, res) => {
      const taskId = parseInt(req.params.id);
      const initialLength = tasks.length;
      tasks = tasks.filter(t => t.id !== taskId);

      if (tasks.length === initialLength) {
        return res.status(404).json({ message: 'Görev bulunamadı' });
      }
      res.status(204).send(); // 204 No Content durumu ile yanıt gönder
    });

    // Hata işleme middleware'i (en sona eklenmeli)
    app.use((err, req, res, next) => {
        console.error(err.stack);
        res.status(500).send('Sunucu tarafında bir hata oluştu!');
    });

    // Sunucuyu başlat
    app.listen(port, () => {
      console.log(Görev API'si http://localhost:${port} adresinde çalışıyor);
    });

3. Çalıştırma ve Test Etme:
Terminalde node app.js komutunu çalıştırın.
Postman, Insomnia gibi bir API test aracı veya curl komut satırı aracı ile API’nizi test edebilirsiniz:

* GET http://localhost:3000/tasks -> Tüm görevleri getirir.
* GET http://localhost:3000/tasks/1 -> ID’si 1 olan görevi getirir.
* POST http://localhost:3000/tasks
* Body (raw, JSON): {"title": "Yeni bir görev", "completed": false}
* PUT http://localhost:3000/tasks/1
* Body (raw, JSON): {"completed": true}
* DELETE http://localhost:3000/tasks/2

Bu örnek, Express ile temel bir REST API’nin nasıl oluşturulduğunu göstermektedir. Gerçek dünya uygulamalarında veriler bir veritabanında saklanır ve daha gelişmiş hata yönetimi, doğrulama ve kimlik doğrulama mekanizmaları kullanılır.

Hata Yönetimi: Uygulamanızı Sağlam Hale Getirin

Her uygulamanın hata yönetimine ihtiyacı vardır. Express’te hataları doğru bir şekilde yönetmek, uygulamanızın beklenmedik durumlarda çökmesini önler ve kullanıcıya anlamlı geri bildirimler sunar.

Senkron ve Asenkron Hatalar

* Senkron Hatalar: Rota işleyici veya middleware içinde senkron olarak oluşan hatalardır. Bunlar otomatik olarak Express’in hata işleme middleware’ine iletilir.

app.get('/sync-error', (req, res, next) => {
        throw new Error('Bu senkron bir hata!'); // Otomatik olarak hata middleware'ine gider
    });

* Asenkron Hatalar: Promise’lar veya callback’ler içinde oluşan asenkron hatalardır. Bunları Express’in hata işleme mekanizmasına iletmek için next(err) kullanmanız gerekir.

app.get('/async-error', async (req, res, next) => {
        try {
            // await bir Promise'ı reddederse, catch bloğu tetiklenir
            await Promise.reject(new Error('Bu asenkron bir hata!'));
        } catch (err) {
            next(err); // Hata işleme middleware'ine ilet
        }
    });

Hata İşleme Middleware’i

Daha önce bahsettiğimiz gibi, Express’te özel bir hata işleme middleware’i, dört argüman alan bir fonksiyondur: (err, req, res, next). Bu, tüm diğer app.use() ve rota tanımlarından sonra en sonda tanımlanmalıdır.

// app.js dosyasının en sonunda
app.use((err, req, res, next) => {
    console.error(err.stack); // Hatayı konsola yazdır (geliştirme ortamında faydalı)

    // Hata tipine göre farklı yanıtlar gönderebilirsiniz
    if (err.name === 'ValidationError') {
        return res.status(400).json({ message: err.message, errors: err.errors });
    }

    res.status(err.status || 500).json({
        message: err.message || 'Beklenmedik bir sunucu hatası oluştu.',
        // Üretim ortamında stack trace göndermeyin!
        // error: process.env.NODE_ENV === 'development' ? err : {}
    });
});

Bu middleware, uygulamanızdaki herhangi bir yerden next(new Error('Hata mesajı')) çağrıldığında tetiklenir.

Proje Yapısı ve En İyi Uygulamalar

Uygulamanız büyüdükçe, kodunuzu düzenli ve yönetilebilir tutmak için iyi bir proje yapısı benimsemek önemlidir.

* Modüler Yapı: Uygulamanızı mantıksal katmanlara ayırın.
* controllers/: İstekleri işleyen ve yanıtları oluşturan iş mantığını içerir.
* routes/: Yönlendirme tanımlarını içerir. express.Router() kullanarak modüler rotalar oluşturulur.
* models/: Veritabanı şemalarını ve veri etkileşim mantığını içerir (veritabanı kullanılıyorsa).
* services/ veya utils/: Ortak yardımcı fonksiyonları veya iş mantığını içerir.
* middleware/: Özel middleware fonksiyonlarını içerir.
* Ortam Değişkenleri (dotenv): Veritabanı bağlantı dizeleri, API anahtarları gibi hassas bilgileri doğrudan kodunuza yazmak yerine ortam değişkenlerinde saklayın. dotenv paketi, .env dosyasındaki değişkenleri process.env nesnesine yüklemenizi sağlar.

npm install dotenv
// app.js'in en başında
    require('dotenv').config();
    const port = process.env.PORT || 3000;
    // ...

* Güvenlik Temelleri:
* helmet: Çeşitli HTTP başlıklarını ayarlayarak uygulamanızın güvenliğini artırır. npm install helmet.
* cors: Çapraz kaynaklı istekleri (Cross-Origin Resource Sharing – CORS) yönetmenizi sağlar. npm install cors.
* Giriş doğrulama (input validation), rate limiting gibi konuları da göz önünde bulundurun.

Sonraki Adımlar: Node.js ve Express ile Sınırları Zorlayın

Node.js ve Express ile temel bir uygulama oluşturmayı öğrendiniz. Ancak bu, sadece başlangıç! İşte bu güçlü ikiliyle yapabileceğiniz ve öğrenmeniz gereken bazı ileri düzey konular:

* Veritabanı Entegrasyonu:
* NoSQL: MongoDB (Mongoose ORM ile), Redis
* SQL: PostgreSQL, MySQL, SQLite (Sequelize veya Knex.js ORM/Query Builder ile)
* Kimlik Doğrulama ve Yetkilendirme:
* JWT (JSON Web Tokens): Kimlik doğrulama için yaygın bir standart.
* OAuth: Üçüncü taraf hizmetlerle (Google, Facebook vb.) entegrasyon.
* Passport.js: Kimlik doğrulama middleware’i.
* Test Yazma: Uygulamalarınızın güvenilirliğini sağlamak için birim testleri (Mocha, Jest), entegrasyon testleri (Supertest) yazmayı öğrenin.
* Deployment (Dağıtım): Uygulamanızı bir sunucuya (Heroku, Vercel, AWS, DigitalOcean vb.) nasıl dağıtacağınızı öğrenin. PM2 gibi süreç yöneticileri, uygulamanızın sürekli çalışmasını sağlar.
* Gerçek Zamanlı Uygulamalar: WebSockets (Socket.IO kütüphanesi ile) kullanarak anlık sohbet uygulamaları, bildirim sistemleri gibi gerçek zamanlı özellikler ekleyin.
* GraphQL: REST API’lerine alternatif olarak GraphQL ile daha esnek ve verimli API’ler oluşturmayı keşfedin.

Sonuç

Node.js ve Express, modern web geliştirmenin vazgeçilmez araçlarıdır. Node.js’in engellemeyen, olay odaklı mimarisi, Express’in minimal ve güçlü web çatısı ile birleştiğinde, yüksek performanslı, ölçeklenebilir ve esnek web uygulamaları ve API’ler oluşturmak için mükemmel bir ortam sunar. Bu makalede, kurulumdan başlayarak temel kavramları, middleware ve yönlendirme mekanizmalarını, basit bir REST API örneğini ve hata yönetimini ele aldık.

Unutmayın, yazılım geliştirme sürekli bir öğrenme sürecidir. Bu rehber size sağlam bir temel sunsa da, pratik yaparak, farklı projeler deneyerek ve Node.js/Express topluluğunun sunduğu kaynakları keşfederek becerilerinizi geliştirmeye devam etmelisiniz. Şimdi klavyenizin başına geçin, kodlamaya başlayın ve Node.js ile Express’in gücünü kendi projelerinizde deneyimleyin!

Yorumlar
İçeriği beğendiniz mi? Bir tartışma başlatın veya görüşlerinizi paylaşın.
Yorum Yaz

Bir yanıt yazın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

E-posta Bülteni
Yazılım Topluluğuna Katılın
En son güncellemeleri, yaratıcı ipuçlarını ve özel kaynakları doğrudan e-posta kutunuza alın. Tasarım ve inovasyonun geleceğini birlikte keşfedelim.