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.
- 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
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
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 😄
Run the following commands to run the unit/integration tests:
❯ yarn install
❯ yarn test:ci
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":"[email protected]", "password":"bar"}' \
http://localhost:3001/api.boilerplate/register
# Authorize your account and retrieve your authentication token
❯ export 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 [email protected] \
-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
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-----`;
}
},
}
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