Skip to content

Instantly share code, notes, and snippets.

@tankist
Created November 13, 2025 13:07
Show Gist options
  • Select an option

  • Save tankist/e1095781d93e2e96d571ed509a19ba30 to your computer and use it in GitHub Desktop.

Select an option

Save tankist/e1095781d93e2e96d571ed509a19ba30 to your computer and use it in GitHub Desktop.
Building a Node.js API Gateway for Microservices Architecture

Building a Node.js API Gateway for Microservices Architecture

!NB: Copyright Somendradev

As your app scales, it often evolves from a monolith into a set of microservices — each responsible for a specific business function. That’s great for scaling teams and codebases, but it introduces a big problem:

How do you give clients a single, seamless entry point while keeping your microservices loosely coupled?

The answer is an API Gateway.

In this post, we’ll break down what an API Gateway is, why you need one, and how to build a Node.js-powered API Gateway with real examples.

What is an API Gateway?

An API Gateway acts as the front door to your entire system:

  • Clients (mobile apps, web apps) send requests only to the gateway.
  • The gateway routes requests to the right microservices.
  • It can handle auth, rate limiting, caching, logging, request/response transformations, and load balancing.

Think of it like an air traffic controller for your microservices.

Why Use an API Gateway?

Without one, every client would need to know:

  • All your microservice URLs
  • Their authentication methods
  • Request and response formats

That’s a maintenance nightmare. An API Gateway centralizes everything, making your architecture easier to maintain and scale.

Key benefits:
✅ Single entry point for clients
✅ Centralized security & logging
✅ Easy scaling and service discovery
✅ Request/response shaping without touching microservices

Tech Stack: What We’ll Use

We’ll build a simple API Gateway with:

  • Node.js + Express.js (lightweight and fast)
  • http-proxy-middleware (for routing requests)
  • JWT Authentication (optional security layer)

Step 1: Setup Your Node.js Gateway

First, initialize a new project:

mkdir api-gateway  
cd api-gateway  
npm init -y  
npm install express http-proxy-middleware jsonwebtoken dotenv

Step 2: Create Basic Express Server

// index.js  
const express = require('express');  
const { createProxyMiddleware } = require('http-proxy-middleware');  
require('dotenv').config();  
  
const app = express();  
  
// Body parser  
app.use(express.json());  
  
// Simple health route  
app.get('/health', (req, res) => res.json({ status: 'API Gateway Running' }));  
  
// Start server  
app.listen(3000, () => {  
  console.log('API Gateway listening on port 3000');  
});

Run node index.js and visit http://localhost:3000/health to confirm it’s working.

Step 3: Add Routing to Microservices

Let’s assume you have these microservices running:

  • User Service: [http://localhost:4001](http://localhost:4001/)
  • Product Service: [http://localhost:4002](http://localhost:4002/)

We’ll set up proxy routes:

// Proxy routes  
app.use('/users', createProxyMiddleware({  
  target: 'http://localhost:4001',  
  changeOrigin: true,  
  pathRewrite: { '^/users': '' }  
}));  
  
app.use('/products', createProxyMiddleware({  
  target: 'http://localhost:4002',  
  changeOrigin: true,  
  pathRewrite: { '^/products': '' }  
}));

Now:

  • GET /users/list → forwards to [http://localhost:4001/list](http://localhost:4001/list)
  • GET /products/123 → forwards to [http://localhost:4002/123](http://localhost:4002/123)

Step 4: Add JWT Authentication (Optional but Recommended)

Centralize authentication at the gateway:

const jwt = require('jsonwebtoken');  
  
// Middleware to verify JWT  
function authenticateToken(req, res, next) {  
  const token = req.headers\['authorization'\]?.split(' ')\[1\];  
  if (!token) return res.status(401).json({ message: 'Unauthorized' });  
  jwt.verify(token, process.env.JWT\_SECRET, (err, user) => {  
    if (err) return res.status(403).json({ message: 'Forbidden' });  
    req.user = user;  
    next();  
  });  
}  
  
// Apply auth for protected routes  
app.use('/products', authenticateToken);

Step 5: Add Logging

In production, logging requests at the gateway helps with monitoring and debugging.

app.use((req, res, next) => {  
  console.log(\`\[${new Date().toISOString()}\] ${req.method} ${req.originalUrl}\`);  
  next();  
});

Optional Features to Level Up Your Gateway

  • Rate Limiting: Use express-rate-limit to throttle requests.
  • Caching: Add Redis or in-memory caching to speed up responses.
  • Service Discovery: Dynamically register and deregister services with Consul or etcd.
  • Circuit Breakers: Prevent cascading failures using opossum.

How the Architecture Looks

           +---------------------+
Client --> |  API Gateway        | --> User Service
           | (Auth, Logging,     | --> Product Service
           |  Rate Limiting)     | --> Other Services
           +---------------------+

Real-World Use Case

Imagine a shopping platform:

  • Frontend calls /products → Gateway routes it to Product Service.
  • Frontend calls /users/orders → Gateway routes to Order Service.
  • Gateway checks JWT token → Blocks unauthenticated users.
  • Gateway logs all activity to ELK stack for analytics.

This setup ensures your frontend never has to know the URLs of your services.

Takeaways

  • An API Gateway is critical for microservice-based apps.
  • Node.js + Express + http-proxy-middleware is a great starting point.
  • You can easily add auth, logging, caching, rate limiting, and service discovery as your system grows.

Start simple, then evolve your gateway into a feature-packed traffic manager for your microservices.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment