Skip to content

khamenkhai/express-drizzle-ts-starter

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Express TypeScript Starter

A production-ready Express.js starter template with TypeScript, featuring authentication, authorization, comprehensive error handling, and modular architecture.

πŸš€ Features

  • βœ… TypeScript - Type safety and better developer experience
  • βœ… Modular Architecture - Feature-based folder structure
  • βœ… Authentication - JWT-based auth with access and refresh tokens
  • βœ… Authorization - Role-based access control (RBAC)
  • βœ… Validation - Request validation using Zod
  • βœ… Error Handling - Centralized error handling with custom error classes
  • βœ… Logging - Winston logger with multiple transports
  • βœ… Security - Helmet, CORS, rate limiting
  • βœ… Environment Config - Type-safe environment variables with validation

πŸ“‹ Prerequisites

  • Node.js (v18 or higher)
  • npm or yarn or pnpm

πŸ› οΈ Installation

  1. Clone or use the template
cd express-ts-starter
  1. Install dependencies
npm install
  1. Set up environment variables
cp .env.example .env

Edit .env and update the values:

NODE_ENV=development
PORT=4000
API_VERSION=v1

JWT_SECRET=your-super-secret-jwt-key-change-this-in-production-minimum-32-chars
JWT_REFRESH_SECRET=your-super-secret-refresh-key-change-this-in-production-minimum-32-chars
JWT_EXPIRES_IN=15m
JWT_REFRESH_EXPIRES_IN=7d

ALLOWED_ORIGINS=http://localhost:4000,http://localhost:5173
  1. Create logs directory
mkdir logs

πŸƒ Running the Application

Development Mode

npm run dev

Production Mode

npm run build
npm start

πŸ“ Project Structure

src/
β”œβ”€β”€ config/               # Configuration files
β”‚   β”œβ”€β”€ env.ts           # Environment variables with validation
β”‚   └── logger.ts        # Winston logger configuration
β”œβ”€β”€ modules/             # Feature modules
β”‚   β”œβ”€β”€ auth/           # Authentication module
β”‚   β”‚   β”œβ”€β”€ auth.controller.ts
β”‚   β”‚   β”œβ”€β”€ auth.service.ts
β”‚   β”‚   β”œβ”€β”€ auth.routes.ts
β”‚   β”‚   └── auth.validation.ts
β”‚   └── users/          # Users module
β”‚       β”œβ”€β”€ user.controller.ts
β”‚       β”œβ”€β”€ user.service.ts
β”‚       β”œβ”€β”€ user.routes.ts
β”‚       └── user.validation.ts
β”œβ”€β”€ shared/             # Shared resources
β”‚   β”œβ”€β”€ database/       # Database models/repositories
β”‚   β”œβ”€β”€ errors/         # Custom error classes
β”‚   β”œβ”€β”€ middleware/     # Express middleware
β”‚   β”œβ”€β”€ types/          # TypeScript types and interfaces
β”‚   └── utils/          # Utility functions
β”œβ”€β”€ routes/             # Route definitions
β”œβ”€β”€ app.ts              # Express app configuration
└── server.ts           # Server entry point

πŸ” Authentication & Authorization

User Roles

  • USER - Regular user
  • MODERATOR - Moderator with elevated permissions
  • ADMIN - Administrator with full access

Authentication Flow

  1. Register: POST /api/v1/auth/register
  2. Login: POST /api/v1/auth/login - Returns access and refresh tokens
  3. Refresh Token: POST /api/v1/auth/refresh - Get new access token
  4. Get Profile: GET /api/v1/auth/profile - Requires authentication
  5. Logout: POST /api/v1/auth/logout - Invalidate token

Authorization

Use the authorize middleware to protect routes:

router.get('/admin-only', 
  authenticate, 
  authorize(UserRole.ADMIN), 
  controller.method
);

πŸ“‘ API Endpoints

Health Check

GET /api/v1/health

Authentication

POST   /api/v1/auth/register      # Register new user
POST   /api/v1/auth/login         # Login user
POST   /api/v1/auth/refresh       # Refresh access token
GET    /api/v1/auth/profile       # Get current user profile (Protected)
POST   /api/v1/auth/logout        # Logout (Protected)

Users (Admin Only)

GET    /api/v1/users              # Get all users (Admin)
GET    /api/v1/users/:id          # Get user by ID (Admin)
PATCH  /api/v1/users/me           # Update current user (Protected)
PATCH  /api/v1/users/:id/role     # Update user role (Admin)
DELETE /api/v1/users/:id          # Delete user (Admin)

πŸ“ API Usage Examples

Register User

curl -X POST http://localhost:4000/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "Password123",
    "firstName": "John",
    "lastName": "Doe"
  }'

Login

curl -X POST http://localhost:4000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "Password123"
  }'

Access Protected Route

curl -X GET http://localhost:4000/api/v1/auth/profile \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

πŸ§ͺ Validation Rules

Registration

  • Email: Valid email format
  • Password: Minimum 8 characters, must contain uppercase, lowercase, and number
  • First/Last Name: Minimum 2 characters

Password Requirements

- Minimum 8 characters
- At least one uppercase letter
- At least one lowercase letter
- At least one number

πŸ›‘οΈ Security Features

  1. Helmet - Sets security-related HTTP headers
  2. CORS - Configurable cross-origin resource sharing
  3. Rate Limiting - Prevents abuse (100 requests per 15 minutes by default)
  4. Password Hashing - Bcrypt with configurable rounds
  5. JWT - Secure token-based authentication
  6. Input Validation - Zod schema validation for all inputs

πŸ”§ Error Handling

The application uses custom error classes for consistent error responses:

  • BadRequestError (400)
  • UnauthorizedError (401)
  • ForbiddenError (403)
  • NotFoundError (404)
  • ConflictError (409)
  • ValidationError (422)
  • InternalServerError (500)

Example error response:

{
  "success": false,
  "message": "User with this email already exists"
}

πŸ“Š Logging

Winston logger with multiple levels:

  • error - Error messages
  • warn - Warning messages
  • info - Informational messages
  • http - HTTP request logs
  • debug - Debug messages (development only)

Logs are saved to:

  • logs/error.log - Error logs only
  • logs/all.log - All logs

πŸ—„οΈ Database

Currently uses an in-memory database for demonstration. Replace src/shared/database/user.db.ts with your preferred database:

  • PostgreSQL with Drizzle or TypeORM
  • MongoDB with Mongoose
  • MySQL with TypeORM

πŸš€ Deployment

  1. Set NODE_ENV=production in your environment
  2. Update JWT_SECRET and JWT_REFRESH_SECRET with strong random values
  3. Configure ALLOWED_ORIGINS for your frontend domains
  4. Set up a real database
  5. Build the application: npm run build
  6. Start the server: npm start

πŸ“¦ Adding New Modules

  1. Create a new folder in src/modules/
  2. Add controller, service, routes, and validation files
  3. Register routes in src/routes/index.ts

Example structure:

src/modules/products/
β”œβ”€β”€ product.controller.ts
β”œβ”€β”€ product.service.ts
β”œβ”€β”€ product.routes.ts
└── product.validation.ts

🀝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Commit your changes
  4. Push to the branch
  5. Open a pull request

πŸ“„ License

MIT

πŸ™ Acknowledgments

Built with best practices for production-ready Express.js applications.

About

REST API boilerplate built with Express.js, TypeScript, Drizzle ORM (MySQL), and Zod. Features complete JWT authentication, role-based access control, and type-safe validation

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors