farkmt2official 1
farkmt2official
kralhakan2009 1
kralhakan2009
Vahsi Uzman 1
Vahsi Uzman
Bvural41 1
Bvural41
Hikaye Ekle

[NODE JS] Express'te JSON Body Parse Etme

nodejs.png


[NODE JS] Express'te JSON Body Parse Etme​


Modern web uygulamalarında istemci ile sunucu arasındaki veri alışverişi büyük ölçüde JSON formatında gerçekleşir. Frontend'den bir form gönderdiğinizde, bir API'ye veri POST ettiğinizde veya mobil uygulamadan istek attığınızda genellikle request body'sinde JSON veri bulunur. Express'te bu JSON verisini parse etmek yani okuyabilir hale getirmek için bir middleware kullanmanız gerekir.

Express 4.16 öncesinde body-parser adlı ayrı bir paket kullanılıyordu. Ama artık bu paket Express'in kendisine entegre edildi. express.json() middleware'i ile JSON body'leri kolayca parse edebilirsiniz. Tek yapmanız gereken app.use(express.json()) satırını route tanımlarınızdan önce eklemek. Bu middleware Content-Type header'ı application/json olan isteklerin body'sini otomatik olarak parse eder ve req.body objesine yazar.

Ben Express'i ilk öğrenirken req.body'nin undefined gelmesinden çok şikayetçi olmuştum. Saatlerce neden veri gelmiyor diye debug etmiştim. Sonra express.json() middleware'ini eklemeyi unuttuğumu fark ettim. Bu çok klasik bir yeni başlayan hatası. Eğer req.body undefined veya boş obje geliyorsa ilk kontrol edeceğiniz şey bu middleware'in ekli olup olmadığı olsun.

express.json() middleware'ine bazı opsiyonlar verebilirsiniz. limit opsiyonu body boyutunu sınırlar, varsayılan 100kb'dir. Büyük JSON verileri kabul etmeniz gerekiyorsa bu limiti artırabilirsiniz ama çok yüksek tutmayın yoksa sunucunuz bellek sorunları yaşayabilir. Ben genellikle 1mb veya 5mb kullanıyorum, daha büyük veriler için dosya upload mekanizması daha uygun.

strict opsiyonu sadece array ve obje kabul etmeyi sağlar. Varsayılan olarak true'dur ve tek başına string, number gibi primitive değerleri reddeder. reviver opsiyonu ile JSON.parse'a özel bir dönüştürme fonksiyonu verebilirsiniz. Mesela tarih string'lerini otomatik olarak Date objesine çevirmek için kullanabilirsiniz.

type opsiyonu ile hangi Content-Type'ların parse edileceğini belirleyebilirsiniz. Varsayılan olarak application/json kabul eder ama bunu genişletebilir veya daraltabilirsiniz. Bazı API'ler application/vnd.api+json gibi özel content type'lar kullanır, bunları da kabul etmek istiyorsanız type opsiyonunu ayarlayın.

verify opsiyonu ham request body'yi almanızı sağlayan bir callback fonksiyonudur. Webhook imza doğrulaması gibi durumlarda ham body'ye ihtiyacınız olur çünkü imza ham string üzerinden hesaplanır. Parse edilmiş objeyi tekrar JSON.stringify yaparsanız orijinal string'den farklı olabilir ve imza doğrulaması başarısız olur.

JSON parse hatalarını yakalamak da önemli. Geçersiz JSON gönderildiğinde express.json() middleware'i SyntaxError fırlatır. Bu hatayı error handling middleware'inizde yakalayıp kullanıcıya anlamlı bir hata mesajı döndürmeniz gerekir. Aksi halde Express varsayılan hata handler'ı çalışır ve çirkin bir HTML hata sayfası gösterir.

Content-Type header'ı eksik olan isteklerde body parse edilmez ve req.body undefined olur. Bu frontend geliştiricilerin sık yaptığı bir hata. fetch API kullanırken headers'a 'Content-Type': 'application/json' eklemeyi unuturlarsa sunucu body'yi parse edemez. API dokümantasyonunuzda bu gerekliliği belirtmenizi tavsiye ederim.

JavaScript:
const express = require('express');
const app = express();

// JSON body parser - temel kullanim
app.use(express.json({{
  limit: '5mb',           // Maksimum body boyutu
  strict: true,            // Sadece array ve obje kabul et
  type: 'application/json', // Hangi content-type parse edilsin
}}));

// Ornek veri deposu (normalde veritabani kullanirsiniz)
let kullanicilar = [
  {{ id: 1, ad: 'Ahmet', email: 'ahmet@test.com', yas: 28 }},
  {{ id: 2, ad: 'Zeynep', email: 'zeynep@test.com', yas: 34 }},
];
let sonrakiId = 3;

// Validasyon yardimci fonksiyonu
function kullaniciValidasyonu(body) {{
  const hatalar = [];

  if (!body.ad || typeof body.ad !== 'string') {{
    hatalar.push('Ad alani zorunludur ve string olmalidir');
  }} else if (body.ad.trim().length < 2) {{
    hatalar.push('Ad en az 2 karakter olmalidir');
  }}

  if (!body.email || typeof body.email !== 'string') {{
    hatalar.push('Email alani zorunludur');
  }} else if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(body.email)) {{
    hatalar.push('Gecerli bir email adresi giriniz');
  }}

  if (body.yas !== undefined) {{
    const yas = Number(body.yas);
    if (isNaN(yas) || yas < 0 || yas > 150) {{
      hatalar.push('Yas 0-150 arasinda olmalidir');
    }}
  }}

  return hatalar;
}}

// POST - Yeni kullanici olustur
app.post('/api/kullanicilar', (req, res) => {{
  // req.body undefined kontrolu
  if (!req.body || Object.keys(req.body).length === 0) {{
    return res.status(400).json({{
      hata: 'Request body bos',
      ipucu: 'Content-Type: application/json header\'i gonderdiginizden emin olun',
    }});
  }}

  // Validasyon
  const hatalar = kullaniciValidasyonu(req.body);
  if (hatalar.length > 0) {{
    return res.status(400).json({{ hatalar }});
  }}

  // Yeni kullanici olustur
  const yeniKullanici = {{
    id: sonrakiId++,
    ad: req.body.ad.trim(),
    email: req.body.email.toLowerCase().trim(),
    yas: req.body.yas ? Number(req.body.yas) : null,
    olusturma: new Date().toISOString(),
  }};

  // Email benzersizlik kontrolu
  if (kullanicilar.some(k => k.email === yeniKullanici.email)) {{
    return res.status(409).json({{ hata: 'Bu email zaten kayitli' }});
  }}

  kullanicilar.push(yeniKullanici);
  res.status(201).json(yeniKullanici);
}});

// PUT - Kullaniciyi tamamen guncelle
app.put('/api/kullanicilar/:id', (req, res) => {{
  const id = parseInt(req.params.id, 10);
  const index = kullanicilar.findIndex(k => k.id === id);

  if (index === -1) {{
    return res.status(404).json({{ hata: 'Kullanici bulunamadi' }});
  }}

  const hatalar = kullaniciValidasyonu(req.body);
  if (hatalar.length > 0) {{
    return res.status(400).json({{ hatalar }});
  }}

  kullanicilar[index] = {{
    ...kullanicilar[index],
    ad: req.body.ad.trim(),
    email: req.body.email.toLowerCase().trim(),
    yas: req.body.yas ? Number(req.body.yas) : null,
    guncelleme: new Date().toISOString(),
  }};

  res.json(kullanicilar[index]);
}});

// PATCH - Kismi guncelleme
app.patch('/api/kullanicilar/:id', (req, res) => {{
  const id = parseInt(req.params.id, 10);
  const index = kullanicilar.findIndex(k => k.id === id);

  if (index === -1) {{
    return res.status(404).json({{ hata: 'Kullanici bulunamadi' }});
  }}

  // Sadece gonderilen alanlari guncelle
  const izinliAlanlar = ['ad', 'email', 'yas'];
  const guncellemeler = {{}};

  for (const alan of izinliAlanlar) {{
    if (req.body[alan] !== undefined) {{
      guncellemeler[alan] = req.body[alan];
    }}
  }}

  kullanicilar[index] = {{
    ...kullanicilar[index],
    ...guncellemeler,
    guncelleme: new Date().toISOString(),
  }};

  res.json(kullanicilar[index]);
}});

// Tum kullanicilari getir
app.get('/api/kullanicilar', (req, res) => {{
  res.json(kullanicilar);
}});

// JSON parse hatasi yakalama
app.use((err, req, res, next) => {{
  if (err instanceof SyntaxError && err.status === 400 && 'body' in err) {{
    return res.status(400).json({{
      hata: 'Gecersiz JSON formati',
      detay: err.message,
      ipucu: 'JSON formatinizi kontrol edin. Ornek: {{"ad": "Ahmet", "email": "a@b.com"}}',
    }});
  }}
  next(err);
}});

app.listen(3000, () => {{
  console.log('JSON body parse sunucusu port 3000\'de');
}});

JSON body parse etme basit görünse de production uygulamalarında dikkat etmeniz gereken çok sayıda detay var. Boyut limitleri, validasyon, hata yönetimi ve güvenlik konularını atlamamanız çok önemli. Özellikle public API'lerde her gelen veriyi potansiyel olarak zararlı kabul edin ve buna göre önlem alın.
 
Emeğiniz ve katkınız için teşekkür ederiz!
Konunuz gerekli incelemelerden geçerek onaylandı. Topluluğumuza katkılarınızın devamını bekliyoruz.
İyi forumlar! 🎉
 

Şu an konuyu görüntüleyenler (Toplam : 0, Üye: 0, Misafir: 0)

Geri
Üst