ABHISHEK7/API_RateLimiter

A self-contained developer portal: sign up, generate API keys, browse interactive Swagger docs, fire live test requests, and watch a rate-limited public API in a usage-analytics dashboard.

★ 0Forks 0JavaScriptGitHub ↗Compare

README

Developer API Rate-Limiter & Developer Portal

A self-contained developer portal: sign up, generate API keys, browse interactive Swagger docs, fire live test requests, and watch a rate-limited public API in a usage-analytics dashboard.

Features

  • Accounts & sessions — email/password signup and login (bcrypt-hashed passwords, JWT sessions).
  • API key lifecycle — generate, regenerate, and revoke keys from the dashboard. Keys are shown in full exactly once, at creation; only a SHA-256 hash and a display fragment are ever persisted.
  • Rate limiting — a sliding-window limiter enforces 60 requests per minute per API key by default (configurable via .env). Exceeding it returns 429 Too Many Requests with Retry-After and X-RateLimit-* headers; every response includes X-RateLimit-Limit / -Remaining / -Reset.
  • Interactive API docs — a full OpenAPI 3.0 spec served through Swagger UI at /api-docs, with a built-in Authorize button so you can paste a key and try endpoints live.
  • Usage analytics — daily request volume, average response time, 429 counts, and a per-key breakdown, all backed by real request logs and rendered with Chart.js.
  • API tester — a request builder in the dashboard to call the public API with any of your keys and watch rate-limit headers change in real time.

Tech stack

  • Backend: Node.js + Express
  • Auth: JSON Web Tokens (portal login) + hashed API keys (public API)
  • Storage: a small file-backed JSON datastore (/data) — no native database driver, so npm install works anywhere without a build toolchain. Swap src/config/db.js for Postgres/Mongo/etc. in production; nothing else in the app needs to change.
  • Docs: swagger-ui-express + a hand-written openapi/openapi.yaml
  • Frontend: plain HTML/CSS/JS (no build step) + Chart.js via CDN

Getting started

npm install
cp .env.example .env      # adjust JWT_SECRET / rate limit if you'd like
npm run seed              # To feed with the sample data
npm start

Then open http://localhost:3000.

Try it with sample data

npm run seed

This creates a demo account ([email protected] / password123) with two API keys and two weeks of realistic usage history, so the analytics charts have something to show immediately. It's safe to run once; running it again is a no-op if the account already has logs.

Project structure

server.js                   Express app entry point
src/
  config/db.js               file-backed JSON datastore
  middleware/
    portalAuth.js             JWT auth for the dashboard's own API
    apiKeyAuth.js              x-api-key auth for the public API
    rateLimiter.js             sliding-window limiter (60 req/min/key)
    requestLogger.js           logs every public-API call for analytics
  models/                     users, apiKeys, usageLogs
  routes/
    auth.routes.js             /auth/signup, /auth/login, /auth/me
    keys.routes.js              /api/keys (CRUD, JWT-protected)
    analytics.routes.js         /api/analytics/* (JWT-protected)
    publicApi.routes.js         /api/v1/* (the rate-limited product API)
  utils/
    apiKey.js                   key generation + hashing
    seedDemo.js                  `npm run seed` script
openapi/openapi.yaml          OpenAPI 3.0 spec powering /api-docs
public/                      dashboard frontend (HTML/CSS/vanilla JS)
data/                        JSON "database" files (created on first run)

The public API

Base path: /api/v1. Every route requires an x-api-key header.

Method Path Description
GET /ping Health check
GET /data List sample records
GET /data/:id Get one sample record
POST /echo Echoes the JSON body you send

Example:

curl http://localhost:3000/api/v1/ping \
  -H "x-api-key: devportal_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Response headers on every call:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1735689600

Once you exceed the limit within the current 60-second window:

HTTP/1.1 429 Too Many Requests
Retry-After: 12

{ "error": "rate_limit_exceeded", "message": "Rate limit of 60 requests per minute exceeded. Try again in 12s.", "limit": 60, "retryAfterSeconds": 12 }

Configuration

All configuration lives in .env (see .env.example):

Variable Default Description
PORT 3000 Port the server listens on
JWT_SECRET — Secret used to sign portal login tokens
RATE_LIMIT_MAX_REQUESTS 60 Requests allowed per window, per API key
RATE_LIMIT_WINDOW_MS 60000 Window length in milliseconds

Notes on the demo datastore

This project ships with a tiny synchronous JSON-file datastore instead of a real database so it runs anywhere with just npm install — no Postgres, no native compiled modules, no Docker required. It's fine for local use and small teams; for a real production deployment, swap src/config/db.js for your database of choice (the rest of the app only calls the functions that module exports, so nothing else needs to change) and move the in-memory rate-limit buckets in src/middleware/rateLimiter.js to Redis if you run more than one server process.

Working Screenshots of the WebApp

Issues