Skip to content

sudo-devKm/routebuilder

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

23 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Node.js TypeScript Route Builder

A robust and scalable Node.js REST API boilerplate built with TypeScript, Express, and MongoDB. Features a custom route builder pattern for rapid API development with built-in CRUD operations.

πŸš€ Features

  • TypeScript - Type-safe development with full TypeScript support
  • Custom Route Builder - Abstract base class for automatic CRUD route generation
  • Express 5 - Latest Express framework with improved performance
  • MongoDB & Mongoose - NoSQL database with ODM for data modeling
  • Security - Helmet, CORS, HPP protection, and security best practices
  • Validation - Schema validation with Zod
  • Error Handling - Centralized error handling middleware
  • Environment Configuration - Type-safe environment variables with Envalid
  • Code Quality - ESLint, Prettier, and Husky for code consistency
  • Development Tools - Hot-reload with Nodemon, path aliases with tsc-alias
  • Logging - Request logging with Morgan and custom logger utility
  • Docker Support - Docker Compose setup with MongoDB
  • Graceful Shutdown - Handles SIGTERM, SIGINT, unhandled exceptions, and closes DB connections cleanly

πŸ“‹ Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js (v18 or higher)
  • npm or yarn
  • Docker & Docker Compose (for containerized MongoDB)
  • Git

πŸ› οΈ Installation

1. Clone the Repository

git clone <repository-url>
cd node-typescript-routebuilder

2. Install Dependencies

npm install

3. Environment Configuration

Create a .env file in the root directory:

# Application
NODE_ENV=development
PORT=5000

# Database
DB_URI=mongodb://admin:admin@localhost:27020/appDb?authSource=admin

# MongoDB Credentials (for Docker Compose)
MONGO_USERNAME=admin
MONGO_PASSWORD=admin
MONGO_DATABASE=appDb

Important: Add .env to your .gitignore file to avoid committing sensitive data.

🐳 Running with Docker

Start MongoDB Container

docker-compose up -d

This will start a MongoDB container with:

  • Port: 27020 (mapped to 27017 internally)
  • Health checks enabled
  • Resource limits configured
  • Persistent volumes for data storage

Stop MongoDB Container

docker-compose down

Stop and Remove Volumes

docker-compose down -v

πŸš€ Running the Application

Development Mode (with hot-reload)

npm run dev

The server will start on http://localhost:5000 with automatic restart on file changes.

Production Build

# Build the project
npm run build

# Start the production server
npm start

Available Scripts

  • npm run dev - Start development server with hot-reload
  • npm run build - Build TypeScript to JavaScript
  • npm start - Build and start production server
  • npm run lint - Run ESLint
  • npm run lint:fix - Fix ESLint errors automatically

πŸ›‘ Graceful Shutdown & Signal Handling

The application is designed to handle process signals and unexpected errors gracefully:

  • SIGTERM and SIGINT (e.g., Ctrl+C) are caught to perform a clean shutdown.
  • Unhandled Promise Rejections and Uncaught Exceptions are logged and trigger cleanup.
  • Database Connection is closed before the process exits.

No manual intervention is neededβ€”these are handled automatically by the app. You will see shutdown logs in the console when the app is stopped or crashes.

πŸ“ Project Structure

β”œβ”€β”€ src/
β”‚   β”œβ”€β”€ app.ts                      # Express app configuration
β”‚   β”œβ”€β”€ index.ts                    # Application entry point
β”‚   β”œβ”€β”€ @types/                     # Custom TypeScript declarations
β”‚   β”‚   └── global/
β”‚   β”œβ”€β”€ config/                     # Configuration files
β”‚   β”‚   └── index.ts                # Environment variables
β”‚   β”œβ”€β”€ exceptions/                 # Custom exception classes
β”‚   β”‚   └── http.exception.ts
β”‚   β”œβ”€β”€ lib/                        # Shared libraries (logger, route-builder, etc.)
β”‚   β”‚   β”œβ”€β”€ logger/                 # Custom logger utility
β”‚   β”‚   └── route-builder/          # Custom Route Builder Library
β”‚   β”‚       β”œβ”€β”€ base.route.ts       # Abstract base route class
β”‚   β”‚       β”œβ”€β”€ generator.ts        # CRUD generator
β”‚   β”‚       β”œβ”€β”€ constants/
β”‚   β”‚       β”œβ”€β”€ interfaces/
β”‚   β”‚       └── types/
β”‚   β”œβ”€β”€ middlewares/                # Express middlewares
β”‚   β”‚   └── errorHandler.ts
β”‚   β”œβ”€β”€ models/                     # Mongoose models
β”‚   β”‚   └── post.entity.ts
β”‚   β”œβ”€β”€ routes/                     # API routes
β”‚   β”‚   β”œβ”€β”€ index.ts
β”‚   β”‚   └── posts/
β”‚   β”‚       └── posts.route.ts
β”‚   └── types/                      # Type definitions
β”œβ”€β”€ docker-compose.yml              # Docker configuration
β”œβ”€β”€ tsconfig.json                   # TypeScript configuration
β”œβ”€β”€ nodemon.json                    # Nodemon configuration
└── package.json                    # Dependencies and scripts

πŸ—οΈ Route Builder Pattern

The custom Route Builder provides automatic CRUD operations for your entities:

Creating a New Route

  1. Define your Mongoose Model (e.g., post.entity.ts)
import mongoose from 'mongoose';

const postSchema = new mongoose.Schema(
  {
    title: { type: String, required: true },
    content: { type: String, required: true },
    author: { type: String, required: true },
  },
  { timestamps: true },
);

export const PostModel = mongoose.model('Post', postSchema);
  1. Create a Route Class (e.g., posts.route.ts)
import { Base } from '@/lib/route-builder/base.route';
import { PostModel } from '@/models/post.entity';

class PostsRoute extends Base<typeof PostModel> {
  constructor() {
    super({
      path: '/posts',
      model: PostModel,
    });
  }
}

export default new PostsRoute();
  1. Register the Route in routes/index.ts
import PostsRoute from './posts/posts.route';

export default [PostsRoute];

Auto-Generated Endpoints

The Route Builder automatically creates the following endpoints:

  • GET /posts - Get all posts
  • GET /posts/:id - Get post by ID
  • POST /posts - Create new post
  • PATCH /posts/:id - Update post (partial)
  • PUT /posts/:id - Replace post (full)
  • DELETE /posts/:id - Delete post

Customization

You can override default behavior using lifecycle hooks and rely on the built-in graceful shutdown for resource cleanup:

class PostsRoute extends Base<typeof PostModel> {
  protected beforePost = async (req, res, next) => {
    // Custom validation or logic before creating a post
    next();
  };

  protected afterGet = async (req, res, next) => {
    // Custom logic after fetching a post
    next();
  };
}

πŸ”’ Security Features

  • Helmet - Sets security-related HTTP headers
  • CORS - Cross-Origin Resource Sharing enabled
  • HPP - HTTP Parameter Pollution protection
  • Compression - Response compression
  • Cookie Parser - Secure cookie parsing

πŸ§ͺ Testing

# Run tests (add your test framework)
npm test

πŸ“ API Documentation

Once the server is running, you can test the API using tools like:

  • Postman
  • Insomnia
  • cURL
  • Thunder Client (VS Code Extension)

Example Request

# Create a new post
curl -X POST http://localhost:5000/posts \
  -H "Content-Type: application/json" \
  -d '{"title":"My First Post","content":"Hello World","author":"John Doe"}'

# Get all posts
curl http://localhost:5000/posts

# Get post by ID
curl http://localhost:5000/posts/:id

🀝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the ISC License.

πŸ‘€ Author

Keyur Machhi

πŸ™ Acknowledgments

  • Express.js community
  • TypeScript team
  • All contributors who help improve this project

Happy Coding! πŸŽ‰

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •