API gateways provide a single entry point for microservices architectures.
Basic Express Gateway#
1import express from 'express';
2import { createProxyMiddleware } from 'http-proxy-middleware';
3
4const app = express();
5
6const services = {
7 users: 'http://users-service:3001',
8 orders: 'http://orders-service:3002',
9 products: 'http://products-service:3003',
10};
11
12app.use(authMiddleware);
13app.use(rateLimiter);
14
15app.use('/api/users', createProxyMiddleware({
16 target: services.users,
17 changeOrigin: true,
18}));
19
20app.use('/api/orders', createProxyMiddleware({
21 target: services.orders,
22 changeOrigin: true,
23}));Request Aggregation#
1app.get('/api/dashboard', async (req, res) => {
2 const [user, orders, recommendations] = await Promise.all([
3 fetch(`${services.users}/${req.user.id}`).then(r => r.json()),
4 fetch(`${services.orders}?userId=${req.user.id}`).then(r => r.json()),
5 fetch(`${services.products}/recommendations`).then(r => r.json()),
6 ]);
7
8 res.json({ user, recentOrders: orders.slice(0, 5), recommendations });
9});Circuit Breaker#
1import CircuitBreaker from 'opossum';
2
3const breaker = new CircuitBreaker(fetchFromService, {
4 timeout: 3000,
5 errorThresholdPercentage: 50,
6 resetTimeout: 30000,
7});
8
9breaker.fallback(() => ({ error: 'Service unavailable' }));
10
11app.get('/api/users/:id', async (req, res) => {
12 const result = await breaker.fire(req.params.id);
13 res.json(result);
14});Health Checks#
1app.get('/health', async (req, res) => {
2 const checks = await Promise.allSettled([
3 fetch(`${services.users}/health`),
4 fetch(`${services.orders}/health`),
5 ]);
6
7 const status = {
8 gateway: 'healthy',
9 services: {
10 users: checks[0].status === 'fulfilled' ? 'healthy' : 'unhealthy',
11 orders: checks[1].status === 'fulfilled' ? 'healthy' : 'unhealthy',
12 },
13 };
14
15 res.status(Object.values(status.services).every(s => s === 'healthy') ? 200 : 503).json(status);
16});API gateways centralize cross-cutting concerns and simplify client interactions.