Skip to content

furkancakici/nodejs-boilerplate

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Node.js API Boilerplate

Enterprise-grade Node.js backend boilerplate with TypeScript, Express, Prisma, and comprehensive error handling.

πŸš€ Features

  • βœ… Routes > Controller > Services architecture
  • βœ… Comprehensive error handling with custom error classes
  • βœ… Structured logging (development & production modes)
  • βœ… Type-safe configuration with Zod validation
  • βœ… Request validation middleware using Zod
  • βœ… Standardized API responses
  • βœ… API versioning (/api/v1)
  • βœ… Graceful shutdown handling
  • βœ… Database connection management (Prisma + SQLite)
  • βœ… Request logging with timing
  • βœ… 404 handling
  • βœ… Async error handling wrapper
  • βœ… TypeScript strict mode
  • βœ… Kebab-case file naming

πŸ“ Project Structure

src/
β”œβ”€β”€ config/              # Configuration management
β”‚   β”œβ”€β”€ config.ts        # Type-safe environment config
β”‚   └── constants.ts     # Application constants
β”œβ”€β”€ controllers/         # Request handlers
β”‚   └── health.controller.ts
β”œβ”€β”€ middleware/          # Express middleware
β”‚   β”œβ”€β”€ async-handler.ts
β”‚   β”œβ”€β”€ error-handler.ts
β”‚   β”œβ”€β”€ not-found.ts
β”‚   β”œβ”€β”€ request-logger.ts
β”‚   └── validate-request.ts
β”œβ”€β”€ routes/              # API routes
β”‚   β”œβ”€β”€ health.route.ts
β”‚   └── index.ts         # Route aggregator
β”œβ”€β”€ services/            # Business logic
β”‚   └── health.service.ts
β”œβ”€β”€ types/               # TypeScript types
β”‚   β”œβ”€β”€ api.types.ts
β”‚   └── express.d.ts
β”œβ”€β”€ utils/               # Utilities
β”‚   β”œβ”€β”€ app-error.ts     # Custom errors
β”‚   β”œβ”€β”€ logger.ts        # Structured logger
β”‚   └── response-formatter.ts
└── index.ts             # Application entry point

πŸ› οΈ Tech Stack

  • Runtime: Node.js
  • Language: TypeScript
  • Framework: Express 5
  • Database: SQLite (via Prisma)
  • ORM: Prisma
  • Validation: Zod
  • Dev Tools: tsx (TypeScript execution)

πŸ“¦ Installation

# Install dependencies
npm install

# Generate Prisma client
npm run prisma:generate

# Run database migrations
npm run prisma:migrate

πŸš€ Usage

Development

npm run dev

Production

# Build
npm run build

# Start
npm start

Database Commands

# Generate Prisma client
npm run prisma:generate

# Run migrations
npm run prisma:migrate

# Open Prisma Studio
npm run prisma:studio

# Reset database
npm run prisma:reset

# Push schema changes
npm run db:push

# Seed database
npm run db:seed

πŸ”Œ API Endpoints

Health Check

  • GET /api/v1/health - Comprehensive health status
  • GET /api/v1/health/ping - Simple ping

Response Format

All API responses follow this structure:

{
  success: boolean,
  data?: any,
  error?: {
    message: string,
    code: string,
    details?: any
  },
  metadata?: {
    timestamp: string,
    requestId?: string,
    pagination?: {
      page: number,
      limit: number,
      total: number,
      totalPages: number
    }
  }
}

πŸ—οΈ Architecture

Routes > Controller > Services Pattern

Route - Defines endpoints and applies middleware

router.get("/", asyncHandler(controller.method));

Controller - Handles HTTP requests/responses

method = asyncHandler(async (req, res) => {
  const data = await this.service.method();
  ResponseFormatter.success(res, data);
});

Service - Contains business logic

async method() {
  // Business logic here
  return data;
}

πŸ›‘οΈ Error Handling

Custom Error Classes

  • AppError - Base error class
  • ValidationError - 400 Bad Request
  • UnauthorizedError - 401 Unauthorized
  • ForbiddenError - 403 Forbidden
  • NotFoundError - 404 Not Found
  • ConflictError - 409 Conflict
  • InternalServerError - 500 Internal Server Error

Usage

throw new NotFoundError("User not found");
throw new ValidationError("Invalid email", "INVALID_EMAIL");

πŸ“ Adding New Features

1. Create Service

// src/services/user.service.ts
export class UserService {
  async getUsers() {
    return await prisma.user.findMany();
  }
}

2. Create Controller

// src/controllers/user.controller.ts
export class UserController {
  private userService = new UserService();
  
  getUsers = asyncHandler(async (req, res) => {
    const users = await this.userService.getUsers();
    ResponseFormatter.success(res, users);
  });
}

3. Create Route

// src/routes/user.route.ts
const router = Router();
const userController = new UserController();

router.get("/", asyncHandler(userController.getUsers));

export default router;

4. Register Route

// src/routes/index.ts
import userRoute from "./user.route.js";
router.use(`${apiPrefix}/users`, userRoute);

πŸ” Request Validation

Using Zod schemas:

import { z } from "zod";
import { validateRequest } from "../middleware/validate-request.js";

const createUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(2),
  age: z.number().min(18).optional(),
});

router.post(
  "/users",
  validateRequest({ body: createUserSchema }),
  asyncHandler(userController.create)
);

πŸ“Š Logging

import { logger } from "./utils/logger.js";

logger.info("User created", { userId: 123 });
logger.error("Database error", error);
logger.warn("Deprecated API used");
logger.debug("Debug information");

βš™οΈ Configuration

Environment variables are validated using Zod:

NODE_ENV=development
PORT=3000
DATABASE_URL=file:./dev.db
GEMINI_API_KEY=your_api_key
CORS_ORIGIN=*
LOG_LEVEL=info

πŸ”’ Best Practices

  • βœ… TypeScript strict mode enabled
  • βœ… No any types (except where necessary)
  • βœ… Async error handling
  • βœ… Request validation
  • βœ… Structured logging
  • βœ… Graceful shutdown
  • βœ… Database connection pooling
  • βœ… Environment validation
  • βœ… Consistent code style
  • βœ… Kebab-case file naming

πŸ“„ License

ISC

πŸ‘¨β€πŸ’» Author

Furkan Γ‡akΔ±cΔ±

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages