Skip to content

Latest commit

 

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Distributed API Gateway & Analytics Engine (TypeScript)

A production-shaped API Gateway built in strict-mode TypeScript. It sits in front of independent backend microservices, handling authentication, rate limiting, request routing, and asynchronous analytics — the kind of infrastructure most applications depend on but rarely build from scratch.

This project began as a JavaScript implementation and was fully rewritten in strict TypeScript to deepen understanding of type-safe backend architecture.

Architecture

Client
  │
  ▼
Rate Limiter (Redis token-bucket-style counter, fail-open on Redis errors)
  │
  ▼
Logger (pushes async job to BullMQ queue, non-blocking)
  │
  ▼
JWT Auth Middleware (per-route, validates token, attaches req.user)
  │
  ▼
Reverse Proxy (http-proxy-middleware, path-rewritten per service)
  │
  ├──▶ Service A — Users API   (port 4001)
  └──▶ Service B — Products API (port 4002)

              Meanwhile, asynchronously:
Logger job ──▶ BullMQ Worker ──▶ MongoDB (persisted log)
                                    │
                                    ▼
                          Recalculates live stats
                                    │
                                    ▼
                    Socket.io ──▶ Real-time dashboard

Features

  • JWT Authentication — token verification middleware with distinct handling for expired vs. malformed tokens, and safe attachment of decoded user data to the request object via TypeScript declaration merging.
  • Redis-backed Rate Limiting — per-client request counting with automatic expiry, and a deliberate fail-open policy: if Redis itself becomes unavailable, requests are still allowed through rather than blocking all traffic.
  • Reverse Proxy Routing — routes requests to independent backend services using http-proxy-middleware, with custom pathRewrite logic to correctly restore the service-specific path after Express strips the mount prefix.
  • Asynchronous Logging — every request is logged via a BullMQ job queue rather than blocking the response cycle. A dedicated worker process consumes these jobs and persists them to MongoDB.
  • Real-Time Analytics Dashboard — a MongoDB aggregation pipeline computes live traffic metrics (total requests, requests/minute, average response time, error rate, top routes), broadcast to connected dashboard clients over Socket.io on every processed log.
  • Strict TypeScript throughout — no implicit any, full strict mode, custom type declarations extending Express's Request type, and generic typing on BullMQ workers and queues.

Tech Stack

Layer Technology
Language TypeScript (strict mode, nodenext module resolution)
Web Framework Express.js
Auth JSON Web Tokens (jsonwebtoken)
Rate Limiting / Caching Redis (ioredis)
Job Queue BullMQ
Database MongoDB (Mongoose)
Real-time Socket.io
Reverse Proxy http-proxy-middleware

Project Structure

API-GATEWAY-TS-/
├── src/
│   ├── middleware/
│   │   ├── auth.ts            # JWT verification middleware
│   │   ├── rateLimiter.ts     # Redis-backed rate limiting
│   │   ├── logger.ts          # Async request logging via BullMQ
│   │   └── proxyMiddleware.ts # Reverse proxy configs for each service
│   ├── services/
│   │   ├── service_A/         # Users microservice
│   │   ├── service_B/         # Products microservice
│   │   └── statsService.ts    # Shared analytics aggregation logic
│   ├── worker/
│   │   ├── index.ts           # BullMQ worker + Socket.io dashboard server
│   │   └── schema/dbSchema.ts # Mongoose log schema
│   ├── config.ts              # Environment variable loading
│   ├── generateToken.ts       # Dev utility for issuing test JWTs
│   └── server.ts              # Main gateway entry point
├── types/
│   └── express.d.ts           # Declaration merging for req.user
├── tsconfig.json
└── package.json

Design Decisions Worth Noting

  • Fail-open rate limiting: prioritizes availability over strict enforcement — if the rate limiter's own dependency (Redis) fails, the system doesn't cascade that failure onto every client request.
  • Path rewriting: Express strips the mount path before handing a request to proxy middleware. pathRewrite explicitly re-prepends the correct service path (/users, /products) rather than assuming the path arrives unchanged.
  • Declaration merging over any: rather than casting req to any to attach authenticated user data, the project extends Express's own Request interface via a dedicated .d.ts file — preserving full type safety on every downstream access to req.user.
  • Decoupled logging: request logging happens through a queue, not inline in the middleware chain, so a slow or failing log write never adds latency to the actual client-facing request.

Getting Started

# Install dependencies
npm install

# Copy environment variables
cp .env.example .env
# fill in JWT_SECRET, MONGO_URI, REDIS_HOST, REDIS_PORT, PORT1, PORT2, PORT

# Run in development
npm run dev

Prerequisites: Redis and MongoDB running locally (or accessible via the connection details in .env).

What I Learned

Converting this project to strict TypeScript surfaced real architectural questions beyond syntax: how to safely extend third-party library types via declaration merging, when a double type-cast through unknown is a legitimate tool versus a red flag, how contextual typing works when passing callbacks into library functions like createProxyMiddleware, and why environment variable loading order matters under ES modules. Debugging the path-rewriting behavior in particular required tracing actual request behavior through Express's internals rather than trusting assumptions about how the path arrives at the proxy layer.

License

MIT

About

A TypeScript-based API Gateway with JWT authentication, Redis-backed rate limiting, async BullMQ logging, reverse proxying to microservices, and a real-time MongoDB-powered analytics dashboard over Socket.io. Full JS-to-strict-TS conversion.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages