Türkiye'de ilk Mobil & PC Aynı Anda Metin2 Oyna. Triarchonline kalıcı ve uzun ömürlü yapısı ile 24 Temmuz'da açılıyor. | 1-99 Mobil Metin2 Triarch HEMEN TIKLA!
[NODE JS] JSON API Donduren Basit Sunucu Yazma
Selam arkadaslar, bugun ogrendigimiz HTTP bilgilerini birlestirip tam calisir bir JSON API sunucusu yazacagiz. Framework kullanmadan, sadece Node.js'in yerlesik modulleriyle production'a yakin bir API olusturacagiz. Ben bu egzersizi yeni baslayanlar icin cok degerli buluyorum cunku Express.js'in kaputun altinda ne yaptigini anlamanizi sagliyor.
API Sunucu Yapisini Kuralim
Guzel bir API sunucusu yazmak icin birkac temel bilesene ihtiyacimiz var: bir router, bir body parser, hata yonetimi, loglama ve CORS destegi. Express.js bunlarin hepsini hazir sunuyor ama biz bunlari kendimiz yazarak ogrenelim. Boylece Express'i kullandigimizda ne yaptigini cok daha iyi anlayacagiz.
JavaScript:
const http = require('http');
const { URL } = require('url');
// ===== YARDIMCI FONKSIYONLAR =====
// JSON cevap gonder
function jsonYanit(res, statusKod, veri) {
const json = JSON.stringify(veri, null, 2);
res.writeHead(statusKod, {
'Content-Type': 'application/json; charset=utf-8',
'Content-Length': Buffer.byteLength(json),
'X-Powered-By': 'NodeJS-Egitim',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
});
res.end(json);
}
// Body oku
function bodyOku(req, maxBoyut = 1024 * 1024) {
return new Promise((resolve, reject) => {
let boyut = 0;
const chunks = [];
req.on('data', chunk => {
boyut += chunk.length;
if (boyut > maxBoyut) {
req.destroy();
reject(Object.assign(new Error('Body cok buyuk'), { statusKod: 413 }));
return;
}
chunks.push(chunk);
});
req.on('end', () => {
const raw = Buffer.concat(chunks).toString();
if (!raw) { resolve(null); return; }
try {
resolve(JSON.parse(raw));
} catch {
reject(Object.assign(new Error('Gecersiz JSON'), { statusKod: 400 }));
}
});
req.on('error', reject);
});
}
// Basit loglama
function logIstek(req, statusKod, sure) {
const renk = statusKod < 400 ? '\x1b[32m' : '\x1b[31m';
const sifirla = '\x1b[0m';
console.log(
`${renk}${req.method} ${req.url} ${statusKod}${sifirla} - ${sure}ms`
);
}
// ===== VERI KATMANI =====
let gorevler = [
{ id: 1, baslik: 'Node.js ogren', tamamlandi: false, oncelik: 'yuksek' },
{ id: 2, baslik: 'API yaz', tamamlandi: false, oncelik: 'orta' },
{ id: 3, baslik: 'Test yaz', tamamlandi: true, oncelik: 'dusuk' }
];
let sonrakiId = 4;
// ===== ROUTER =====
const rotalar = {};
function rotaEkle(metod, yol, isleyici) {
const anahtar = `${metod} ${yol}`;
rotalar[anahtar] = isleyici;
}
function rotaBul(metod, yol) {
// Once tam eslestir
const tamAnahtar = `${metod} ${yol}`;
if (rotalar[tamAnahtar]) {
return { isleyici: rotalar[tamAnahtar], params: {} };
}
// Sonra parametrik eslesme
for (const [rota, isleyici] of Object.entries(rotalar)) {
const [rotaMetod, rotaYol] = rota.split(' ');
if (rotaMetod !== metod) continue;
const rotaParcalari = rotaYol.split('/');
const yolParcalari = yol.split('/');
if (rotaParcalari.length !== yolParcalari.length) continue;
const params = {};
let eslesti = true;
for (let i = 0; i < rotaParcalari.length; i++) {
if (rotaParcalari[i].startsWith(':')) {
params[rotaParcalari[i].slice(1)] = yolParcalari[i];
} else if (rotaParcalari[i] !== yolParcalari[i]) {
eslesti = false;
break;
}
}
if (eslesti) return { isleyici, params };
}
return null;
}
// ===== ROUTE TANIMLARI =====
// GET /api/gorevler - Tum gorevleri listele
rotaEkle('GET', '/api/gorevler', (req, res) => {
const url = new URL(req.url, `http://${req.headers.host}`);
let sonuc = [...gorevler];
// Filtreleme
const durum = url.searchParams.get('durum');
if (durum === 'tamamlandi') sonuc = sonuc.filter(g => g.tamamlandi);
if (durum === 'bekleyen') sonuc = sonuc.filter(g => !g.tamamlandi);
jsonYanit(res, 200, { toplam: sonuc.length, gorevler: sonuc });
});
// GET /api/gorevler/:id
rotaEkle('GET', '/api/gorevler/:id', (req, res, params) => {
const gorev = gorevler.find(g => g.id === parseInt(params.id));
if (!gorev) return jsonYanit(res, 404, { hata: 'Gorev bulunamadi' });
jsonYanit(res, 200, gorev);
});
// POST /api/gorevler
rotaEkle('POST', '/api/gorevler', async (req, res) => {
const body = await bodyOku(req);
if (!body || !body.baslik) {
return jsonYanit(res, 400, { hata: 'baslik alani zorunlu' });
}
const yeniGorev = {
id: sonrakiId++,
baslik: body.baslik,
tamamlandi: false,
oncelik: body.oncelik || 'orta',
olusturma: new Date().toISOString()
};
gorevler.push(yeniGorev);
jsonYanit(res, 201, yeniGorev);
});
// PUT /api/gorevler/:id
rotaEkle('PUT', '/api/gorevler/:id', async (req, res, params) => {
const index = gorevler.findIndex(g => g.id === parseInt(params.id));
if (index === -1) return jsonYanit(res, 404, { hata: 'Gorev bulunamadi' });
const body = await bodyOku(req);
gorevler[index] = { ...gorevler[index], ...body, id: gorevler[index].id };
jsonYanit(res, 200, gorevler[index]);
});
// DELETE /api/gorevler/:id
rotaEkle('DELETE', '/api/gorevler/:id', (req, res, params) => {
const index = gorevler.findIndex(g => g.id === parseInt(params.id));
if (index === -1) return jsonYanit(res, 404, { hata: 'Gorev bulunamadi' });
const silinen = gorevler.splice(index, 1)[0];
jsonYanit(res, 200, { mesaj: 'Silindi', gorev: silinen });
});
// ===== SUNUCU =====
const sunucu = http.createServer(async (req, res) => {
const baslangic = Date.now();
// CORS preflight
if (req.method === 'OPTIONS') {
res.writeHead(204, {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE',
'Access-Control-Allow-Headers': 'Content-Type'
});
res.end();
return;
}
const url = new URL(req.url, `http://${req.headers.host}`);
const eslesme = rotaBul(req.method, url.pathname);
try {
if (eslesme) {
await eslesme.isleyici(req, res, eslesme.params);
} else {
jsonYanit(res, 404, { hata: 'Endpoint bulunamadi' });
}
} catch (error) {
const kod = error.statusKod || 500;
jsonYanit(res, kod, { hata: error.message });
}
logIstek(req, res.statusCode, Date.now() - baslangic);
});
sunucu.listen(3000, () => {
console.log('API Sunucusu calisiyor: http://localhost:3000');
console.log('\nKullanilabilir endpoint\'ler:');
Object.keys(rotalar).forEach(r => console.log(` ${r}`));
});
Sonuc
Gordugunuz gibi, framework olmadan da gayet duzgun bir API sunucusu yazilabiliyor. Ama production'da Express.js veya Fastify gibi framework'ler kullanmanizi siddetle tavsiye ederim cunku routing, middleware zinciri, hata yonetimi, validation gibi bir cok konuda hazir cozumler sunuyorlar. Bu yaziinin amaci altyapiyi anlamaniz, her projenizi sifirdan yazmaniz degil. Sonraki konumuz HTML sayfasi donduren sunucu!
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!
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)
Benzer konular
- Cevaplar
- 0
- Görüntüleme
- 52
- Cevaplar
- 2
- Görüntüleme
- 56
- Cevaplar
- 4
- Görüntüleme
- 299
Altın Konu
Next.js'de API Oluşturma Ve Kullanma
- Cevaplar
- 12
- Görüntüleme
- 1K
