qhantom / express-mongo-typescript-boilerplate

A production-ready boilerplate based on Node.js, Express and MongoDB (using Mongoose ODM) written in TypeScript. It gets you up and running very fast to quickly build RESTful APIs.
MIT License
10 stars 1 forks source link
Node.js | Express | MongoDB | TypeScript
A production-ready boilerplate based on Node.js, Express and MongoDB (using Mongoose ODM) written in TypeScript. It gets you up and running very fast to quickly build RESTful APIs.
Feel free to contribute

GitHub license

Features

MongoDB
NoSQL database using Mongoose ODM
Authentication
JWT-based authentication with Passport
Roles and Rights
Create custom roles and assign custom rights to them in order to protect routes with specific rights
Logging
using winston as logger and morgan as HTTP request logger middleware (if running in a Docker container, the logs are sent to stdout of the Docker daemon)
Validation
validate the request body with express-validator
Process Manager
PM2 as process manager to keep the app alive
Mailing
send e-mails using Nodemailer and test your set-up with Ethereal
Task Scheduler
schedule tasks with node-cron
Security
takes care of the application security with Helmet, Express Mongoose Sanitize, Express Rate Limit
Environment Variables
using dotenv (you can change the .env file inside the nodemon.json file)
Docker / Docker-Compose support
simply modify the Dockerfile and docker-compose.yml to fit your needs
Compression
gzip compression with compression
Git hooks
using husky and conventional commits
Linting & Formatting
with Prettier and ESLint following the Airbnb's ESLINT config with TypeScript support
Error Handling
centralized error handling
Static Content
Serve static content via the public folder
Versioning
Using standard version to version your project following semver

Run the app

Locally

Install dependencies: npm install or yarn

Start development server using Nodemon: npm run dev

Keep in mind that Docker is not used here. Instead, the environment variable DATABASE_URI gets accessed.

Docker(-Compose)

docker-compose up

Docker-Compose automatically creates a Node.js container using the Dockerfile as well as a MongoDB container using the mongo:4.4.5-bionic image.

Start the Node.js container only docker build <project-dir> -t node-app

Environment variables

The NODE_ENV environment variable is set inside nodemon.json for development and in the Dockerfile for production. If you don't use Docker in production, you can set the NODE_ENV variable in the ecosystem.config.json file (PM2 config file) like so:

{
  "apps": [
    {
      "name": "app",
      "script": "index.js",
      "instances": 1,
      "autorestart": true,
      "time": true,
      "env_production": {
        "NODE_ENV": "production"
      }
    }
  ]
}
SERVER_PORT=3000

DATABASE_URI=mongodb://127.0.0.1:27017/express-boilerplate

JWT_SECRET=your-secret
JWT_EXPIRATION_HOURS=24
JWT_ISSUER=Express Boilerplate

SMTP_HOST=mail-server
TP_PORT=587
SMTP_USERNAME=mail-server-username
SMTP_PASSWORD=mails-server-password
EMAIL_FROM=mail-sender

Project Structure

src\
 |--config\         # Environment variables and configurations
 |--controllers\    # Route controllers
 |--middlewares\    # Middlwares
 |--models\         # Mongoose models
 |--routes\         # Routes
 |--services\       # Business logic
 |--types\          # Custom types
 |--app.ts          # Express app
 |--index.ts        # Entry point

API

Endpoints

Auth routes

POST /v1/auth/register - body: { email: string, password: string }

POST /v1/auth/login - body: { email: string, password: string }

GET /v1/auth/me

GET /v1/auth/logout

User routes

GET /v1/users

GET /v1/users/:id

POST /v1/users - body: { email: string, password: string }

PUT /v1/users/:id - body: { email: string, password: string }

DELETE /v1/users/:id

Right routes

GET /v1/rights

GET /v1/rights/:id

POST /v1/rights - body: { name: string, description?: string }

PUT /v1/rights/:id - body: { name: string, description?: string }

DELETE /v1/rights/:id

Role routes

GET /v1/roles

GET /v1/roles/:id

POST /v1/roles - body: { name: string, description?: string, rights?: ObjectId[] }

PUT /v1/roles/:id - body: { name: string, description?: string, rights?: ObjectId[] }

DELETE /v1/roles/:id