Mikroservis mimarisi, tek bir uygulamayı küçük, bağımsız çalışan servisler olarak bölme felsefesiyle yükseliyor. Node.js, hafif yapısı ve etkin/az bellek tüketimi sayesinde bu yaklaşım için en popüler dillerden birini oluşturuyor. Burada, mikroservislerin temel kavramlarını tanıttıktan sonra, Express, Docker ve Docker Compose ile gerçekçi bir örnek üzerinden adım adım ilerleyeceğiz.
Mikroservis, tek bir işlevi yerine getiren ve kendi veri tabanına sahip olan bağımsız bir bileşen olarak tanımlanır.
Node.js, event‑driven ve non‑blocking I/O modeli sayesinde aynı anda birçok bağlantıyı yönetebilir. Bu, mikroservis ortamında içerik yönetim, veri işleme, telemetri gibi görevleri eşzamanlı şekilde yönetmek için ideal.
Projemizde üç mikroservis öne çıkacak: Auth Service, Product Service ve Order Service. Her servis kendi Express sunucusuna, Docker konteynerine ve JSON‑tabanlı bir veri deposuna (örnek olarak SQLite) sahip olacak.
npm init -y
npm install express jsonwebtoken bcryptjs body-parser
Auth servisinin temel kod bloğu:
const express = (() => {
const app = express();
app.use(express.json());
const users = [];
app.post('/register', (req, res) => {
const { email, password } = req.body;
const hashed = bcryptjs.hashSync(password, 10);
users.push({ email, password: hashed });
res.json({ message: 'Kayıt başarılı' });
});
app.post('/login', (req, res) => {
const { email, password } = req.body;
const user = users.find(u => u.email === email);
if (!user || !bcryptjs.compareSync(password, user.password)) return res.status(401).json({ error: 'Geçersiz kimlik bilgisi' });
const token = jsonwebtoken.sign({ email }, 'secret-key', { expiresIn: '1h' });
res.json({ token });
});
app.listen(3001, () => console.log('Auth Service listening on 3001'));
})();
npm install express sqlite3
Product servisinde tarayıcıdan ürünleri ekleyip listeleyebileceğiz. Basit SQLite tablosu ile örnek uç noktalar:
const express = (() => {
const app = express();
app.use(express.json());
const db = new sqlite3.Database(':memory:');
db.run("CREATE TABLE products(id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, price REAL)");
app.post('/products', (req, res) => {
const { name, price } = req.body;
db.run("INSERT INTO products(name, price) VALUES(?,?)", [name, price]);
res.json({ message: 'Ürün eklendi' });
});
app.get('/products', (req, res) => {
db.all("SELECT * FROM products", [], (err, rows) => {
if (err) return res.status(500).json({ error: err.message });
res.json(rows);
});
});
app.listen(3002, () => console.log('Product Service listening on 3002'));
})();
Order servisi, Auth ve Product servislerinikullanarak sipariş oluşturacak. İçerik doğrulaması için axios kullanılacak.
npm install express axios jsonwebtoken body-parser
const express = (() => {
const app = express();
app.use(express.json());
app.post('/orders', async (req, res) => {
const token = req.headers.authorization?.split(' ')[1];
if (!token) return res.status(401).json({ error: 'Token yok' });
try {
const decoded = jsonwebtoken.verify(token, 'secret-key');
const { products } = req.body; // array of { id, quantity }
const productDetails = await Promise.all(products.map(async p => {
const response = await axios.get(`http://product:3002/products`).then(r => r.data.find(d => d.id === p.id));
return { ...p, name: response.name, price: response.price };
}));
const total = productDetails.reduce((t, p) => t + p.price * p.quantity, 0);
res.json({ user: decoded.email, items: productDetails, total });
} catch (e) {
res.status(401).json({ error: 'Geçersiz token' });
}
});
app.listen(3003, () => console.log('Order Service listening on 3003'));
})();
Her servisin Dockerfile’ı tek satır: node:18-slim tabanında bağımlılıkları indirip başlatma komutunu kullanabilirsiniz.
# Dockerfile (örnek)
FROM node:18-slim
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3001
CMD ["node", "index.js"]
Şimdi tüm servisleri aynı dosyada tanımlayabileceğimiz docker-compose.yml:
version: '3.8'
services:
auth:
build: ./auth
ports:
- '3001:3001'
networks:
- api-network
product:
build: ./product
ports:
- '3002:3002'
networks:
- api-network
order:
build: ./order
ports:
- '3003:3003'
depends_on:
- auth
- product
environment:
- AUTH_SERVICE=http://auth:3001
- PRODUCT_SERVICE=http://product:3002
networks:
- api-network
networks:
api-network:
Bu yapı sayesinde her servis kendi konteynerde çalışır, aynı zamanda servisler birbirine tanımlı ağ üzerinden ulaşır.
/health ile kontrol edilmesi sağlanmalı.swagger-jsdoc kullanabilirsiniz.packages klasörleriyle servisleri ayrı klasörlerde tutabilirsiniz.docker buildx kullanarak hızlı images elde edebilirsiniz.Node.js ile mikroservis mimarisi, ölçeklenebilirliği, esnekliği ve hızlı geliştirme döngülerini bir araya getiriyor. Docker Compose ile basit bir ortamda bile üretime hazır bir deneme ortamı oluşturabilirsiniz. Bu rehberde gösterilen temel yapı, gerçek dünya senaryolarında genişletilebilecek sağlam bir başlangıç noktası sağlar.