TommyStarK / typescript-api-boilerplate

A simple and modular RESTful API boilerplate written in Typescript using Express, MongoDB and PostgreSQL.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

typescript-api-boilerplate

Build Status codecov DeepScan gradeMIT licensed

A simple and modular RESTful API boilerplate written in Typescript using Express. The boilerplate is backed with a Mongodb and a PostgreSQL.

Some features have been integrated into the boilerplate. The idea is to have some basic components and a clear architecture to easily implement new ones:

  • Account management (register/unregister an account)
  • Authentication
  • Per-User media management system (upload/download/list/delete pictures)

The goal is to define a healthy architecture of a REST API connected to one or more backend(s), in this case a PostgreSQL to store user data and a MongoDB to store pictures of each user. The whole accompanied by a simple authentication system.

Note: Only hashes of password are stored in the database. Use the hash function in the utils/crypto module if you have to compare hashes.

Same for emails, they are encrypted using AES256 before being stored. Use the decrypt function in the utils/crypto module if you need to decrypt stored email.

Features

  • Authentication using JSON Web Tokens
  • Configurable connections pools for backend storages
  • Cross-Origin Resource Sharing enabled (including browser preflight request)
  • Custom exception(s) filter
  • Data input validation middlewares thanks to class-validator
  • ECMAScript 2021
  • Inversion of Control container with Inversify
  • Logging interceptor using Winston
  • Native storage drivers
  • MongoDB automatic collections validation
  • PostgreSQL atomic queries execution on demand
  • Supports HTTP/HTTPS
  • Uses Yarn over npm
  • Testing with Jest

Requirements

For MacOS, add the following paths to your docker engine:

  • /var/lib/mongo/data/db
  • /var/lib/postgres

This can be done through Docker -> Preferences -> File sharing

Contribution

Each Contribution is welcomed and encouraged. I don't claim to cover each use cases nor completely master the Node.js. If you encounter a non sense or any trouble, you can open an issue and I will be happy to discuss about it 😄

Tests

Run the following commands to run the unit/integration tests:

❯ yarn install
❯ yarn test:ci

Usage

Run the following commands to use your boilerplate:

# Start the stack
❯ docker-compose up --build --detach

#
# Assuming your are using the default config
#

# healthcheck
❯ curl --request GET http://localhost:3001/api.boilerplate/healthz

# Register a new account
❯ curl -H "Content-Type: application/json" --request POST \
 -d '{"username":"foo", "email":"foo@email.com", "password":"bar"}' \
 http://localhost:3001/api.boilerplate/register

# Authorize your account and retrieve your authentication tokenexport TOKEN=$(curl --silent -H "Content-Type: application/json" --request POST \
 -d '{"username":"foo", "password":"bar"}' \
 http://localhost:3001/api.boilerplate/authorize | jq -r .token)

# Test an auth required endpoint
❯ curl -H "Authorization: $TOKEN" --request GET \
 http://localhost:3001/api.boilerplate/hello

# Upload a picture (okay this is not a picture ... :p)
❯ curl -H "Authorization: $TOKEN" -F file=@README.md \
 -X POST http://localhost:3001/api.boilerplate/picture

# Get your pictures
❯ curl -H "Authorization: $TOKEN" --request GET \
 http://localhost:3001/api.boilerplate/pictures

# Get a specific picture
❯ curl -H "Authorization: $TOKEN" --request GET \
 http://localhost:3001/api.boilerplate/picture/PICTURE_ID

# Delete a specific picture
❯ curl -H "Authorization: $TOKEN" --request DELETE \
 http://localhost:3001/api.boilerplate/picture/PICTURE_ID

# Unregister your account
❯ curl -H "Content-Type: application/json" --request DELETE \
 -d '{"username":"foo", "password":"bar"}' \
 http://localhost:3001/api.boilerplate/unregister

Customization

Config

Check the config file to customize your boilerplate as you wish.

Here is an example:

{
  app: {
    url: 'api.boilerplate',
    port: 3001,
    production: false,
    secret: '1S3cR€T!',
    expiresIn: '24h',
    https: {
      port: 8443,
      tls: {
        certificate: 'tls/server.crt',
        key: 'tls/key.pem',
      },
    },
  },
  mongo: {
    database: 'dummy',
    host: process.env.MONGO_URI || 'localhost',
    port: '27017',
  },
  postgres: {
    database: 'dummy',
    host: process.env.POSTGRES_URL || '127.0.0.1',
    port: 5432,
    max: 10,
    user: 'root',
    password: 'root',
    ssl: {
      rejectUnauthorized: true,
      ca: `-----BEGIN CERTIFICATE-----
MIIDHTCCAgWgAwIBAgIUVia1fkXIlMxFcihoygqh6b+z7JMwDQYJKoZIhvcNAQEL
BQAwHjEcMBoGA1UEAwwTSUJNIENsb3VkIERhdGFiYXNlczAeFw0xODEwMTExNDQ4
          .............................
MrPXxLy9NPj8isOutrLD29IY2A0V4RlcIxS0L7sVOy0zD6pmzMMQMD/5ifuIX6bq
lJeg5xjKvO+plIKMhOSQyu4T0MMy6fckwMZO+IbGrCdr
-----END CERTIFICATE-----`;
    }
  },
}

HTTPS

To enable https, you must add your tls certificate and key to tls/ before running your boilerplate:

To generate self-signed certificate, run the following commands:

❯ openssl req -newkey rsa:2048 -new -nodes \
  -keyout tls/key.pem -out tls/csr.pem

❯ openssl x509 -req -days 365 -in tls/csr.pem \
  -signkey tls/key.pem -out tls/server.crt

About

A simple and modular RESTful API boilerplate written in Typescript using Express, MongoDB and PostgreSQL.

License:MIT License


Languages

Language:TypeScript 89.9%Language:Shell 9.4%Language:JavaScript 0.5%Language:Dockerfile 0.3%