A production-level REST API platform built with Node.js, Express.js, TypeScript, and MongoDB that enables user authentication, secure API key management, API protection, and usage tracking.
This project focuses on backend architecture, security, scalability, and maintainability while following modern development practices such as ESLint, Prettier, Husky, and feature-based modular architecture.
- User Registration
- User Login
- JWT-based Authentication
- Password Hashing using bcrypt
- Protected Routes
- Generate secure API Keys
- Store hashed API Keys in MongoDB
- Activate / Deactivate API Keys
- API Key Authentication Middleware
- Protect APIs using JWT Authentication
- Protect APIs using API Keys
- Rate Limiting
- Request Tracking
- Feature-based Folder Structure
- Controller → Service → Model Architecture
- Global Error Handling
- Custom Error Classes
- Environment Variable Management
- TypeScript
- ESLint
- Prettier
- Husky
- lint-staged
- pnpm
- Express 5
| Category | Technology |
|---|---|
| Runtime | Node.js |
| Framework | Express.js |
| Language | TypeScript |
| Database | MongoDB Atlas |
| ODM | Mongoose |
| Authentication | JWT |
| Password Hashing | bcrypt |
| API Key Security | SHA-256 |
| Package Manager | pnpm |
| Linting | ESLint |
| Formatting | Prettier |
| Git Hooks | Husky + lint-staged |
The following diagram shows how every request travels through the application from the client to MongoDB and back.
CLIENT
(Browser / Postman)
│
HTTP Request (GET/POST)
│
Express Server (server.ts)
│
Express App (app.ts)
│
┌────────────────────────┴────────────────────────┐
│ │
express.json() Global Middleware
(Error Handler, Future Middleware)
│
└────────────────────────┬────────────────────────┘
Root Router (/api/v1)
│
┌───────────────┬─────────┴──────────┬
/auth /api-keys /api
│ │ │
Route File Route File Route File
│ │ │
Controller Controller Controller
│ │ │
Service Service Service
(Business Logic) (Business Logic) (Business Logic)
│ │ │
JWT Utils / API Key Utils Validation
Password Hashing SHA-256 Hashing
│ │
└───────────────┼────────────────────┐
Mongoose Models Shared Models
│
MongoDB Atlas
│
Read / Write Documents
│
Mongoose Result
│
Service
│
Controller
│
JSON Response Returned
│
CLIENT
This architecture makes it easy to extend the project by adding new modules without affecting existing functionality.
- The client sends an HTTP request to the Express server.
server.tsstarts the application and forwards the request toapp.ts.- Global middleware executes (JSON parsing, error handling, etc.).
- The request is routed through the root router (
/api/v1). - The appropriate feature module is selected.
- The controller receives the request and extracts required data.
- The controller delegates business logic to the service layer.
- The service validates data, performs security checks, and executes business logic.
- Database operations are performed through Mongoose models.
- MongoDB processes the query and returns the result.
- The service formats the business response.
- The controller converts it into an HTTP response.
- Express sends the JSON response back to the client.
src
│
├── config/
│ └── db.ts
│
├── middlewares/
│ ├── auth.middleware.ts
│ ├── apiKey.middleware.ts
│ └── error.middleware.ts
│
├── models/
│ └── user.model.ts
│
├── modules/
│ ├── auth/
│ │ ├── auth.routes.ts
│ │ ├── auth.controller.ts
│ │ ├── auth.service.ts
│ │ └── auth.model.ts
│ │
│ ├── api/
│ │ ├── api.routes.ts
│ │ ├── api.controller.ts
│ │ ├── api.service.ts
│ │ └── api.model.ts
│ │
│ └── api-key/
│ ├── apiKey.routes.ts
│ ├── apiKey.controller.ts
│ ├── apiKey.service.ts
│ └── apiKey.model.ts
│
├── routes/
│ └── root.routes.ts
│
├── utils/
│ ├── jwt.ts
│ └── appError.ts
│
├── app.ts
└── server.ts
| Folder | Responsibility |
|---|---|
config |
Database and application configuration |
middlewares |
Authentication, API key validation and global error handling |
models |
Shared database models |
modules |
Feature-based business modules |
routes |
Root application routing |
utils |
Reusable helper utilities |
app.ts |
Express application configuration |
server.ts |
Application entry point |
Make sure the following tools are installed on your machine:
- Node.js (v20 or later recommended)
- pnpm
- MongoDB Atlas account (or local MongoDB instance)
- Git
git clone https://github.com/ARYAN0-work/API-STORE.git
cd API-STOREpnpm installCreate a .env file in the project root.
cp .env.example .envUpdate the variables:
MONGO_URI=
JWT_SECRET=
PORT=pnpm devIf the MongoDB connection is successful, you'll see logs similar to:
Connecting to MongoDB...
Database connected successfully!
Server is listening on port 5000
Compile the TypeScript project:
pnpm buildRun the compiled application:
pnpm start| Command | Description |
|---|---|
pnpm dev |
Start development server with hot reload |
pnpm build |
Compile TypeScript into JavaScript |
pnpm start |
Run compiled production build |
pnpm lint |
Run ESLint |
pnpm lint:fix |
Automatically fix lint issues |
pnpm format |
Format the project using Prettier |
The API is versioned using the /api/v1 prefix.
| Method | Endpoint | Authentication | Description |
|---|---|---|---|
| GET | /api/v1/ |
Verify that the server is running |
| Method | Endpoint | Authentication | Description |
|---|---|---|---|
| POST | /api/v1/auth/register |
Register a new user | |
| POST | /api/v1/auth/login |
Authenticate a user and return a JWT |
| Method | Endpoint | Authentication | Description |
|---|---|---|---|
| POST | /api/v1/api-keys/generate |
JWT | Generate a new API Key |
| GET | /api/v1/api-keys |
JWT | Retrieve all API Keys belonging to the authenticated user |
| PATCH | /api/v1/api-keys/:id/toggle |
JWT | Activate or deactivate an API Key |
| DELETE | /api/v1/api-keys/:id |
JWT | Delete an API Key |
| Method | Endpoint | Authentication | Description |
|---|---|---|---|
| GET | /api/v1/api/... |
API Key | Access protected APIs using a valid API Key |
Include the JWT token in the Authorization header.
Authorization: Bearer <jwt_token>Include the API key in the request headers.
x-api-key: api_key| Status Code | Meaning |
|---|---|
| 200 | Request successful |
| 201 | Resource created successfully |
| 400 | Bad request |
| 401 | Unauthorized |
| 429 | Too many requests |
| 500 | Internal server error |
JWT (JSON Web Token) is used to authenticate users after a successful login.
The generated token contains the authenticated user's identifier and is required to access protected endpoints.
User passwords are never stored in plain text.
Passwords are hashed using bcrypt before being stored in MongoDB.
Benefits:
- Prevents password leakage
- One-way hashing
Generated API Keys are never stored directly inside the database.
This ensures that even if the database is compromised, original API Keys cannot be recovered.
Sensitive configuration values are stored inside environment variables.
Examples include:
- MongoDB connection string
- JWT Secret
- Server Port
The .env file is ignored using Git, while .env.example documents the required configuration for contributors.
A centralized error handling middleware is used to provide consistent error responses throughout the application.
Instead of organizing files by type, the project follows a feature-based architecture.
Each feature owns its:
- Routes
- Controller
- Service
- Model
This improves maintainability and allows new modules to be added without affecting existing features.
Business logic is intentionally separated into layers.
- Receives HTTP requests
- Validates incoming data
- Returns HTTP responses
- Contains business logic
- Coordinates database operations
- Handles validations
- Communicates with utilities
- Represents database schemas
- Performs MongoDB operations using Mongoose
Used to detect potential bugs and enforce coding standards.
Automatically formats the codebase to maintain a consistent style.
Runs Git hooks before every commit.
Ensures only staged files are linted and formatted before committing.
Together, these tools help maintain a clean and consistent codebase throughout development.
API Keys maintain usage information including request count and request window.
Each request:
- Validates the API Key
- Checks the request count
- Resets the window after one hour
- Rejects requests exceeding the configured limit with HTTP 429 (Too Many Requests)
This protects APIs from abuse and excessive usage.
Aryan Mishra
MERN-Stack Developer | Computer Science Student
Special thanks to the open-source community and the creators of the tools and libraries that made this project possible:
- Node.js
- Express.js
- TypeScript
- MongoDB & Mongoose
- JSON Web Token (JWT)
- bcrypt
- ESLint
- Prettier
- Husky
- pnpm
All endpoints were tested using Insomnia.