ACK NestJs Boilerplate π₯ π
Http NestJs v9.x boilerplate. Best uses for backend service.
You can request feature or report bug with following this link
Table of contents
- Important
- Next Todo
- Build With
- Objective
- Features
- Prerequisites
- Getting Started
- API Reference
- Environment
- Api Key Encryption
- Adjust Mongoose Setting
- License
- Contact
Important
If you change the environment value of APP_ENV
to production
, that will trigger.
- CorsMiddleware will implement
src/configs/middleware.config.ts
, else the default is*
. - Documentation will
disable
. - Encrypt the payload of JWT.
Next Todo
Next development
- Implement Repository Design Pattern / Data Access Object Design Pattern
- Swagger for API Documentation
- Mongo Repository soft delete
- Make it simple
- Encrypt jwt payload
- Optimize Unit Testing
- Make serverless separate repo
- Optimize Swagger (Ongoing)
- Add Relational Database Repository, ex: mysql, postgres (Ongoing)
- Update Documentation, include an diagram for easier comprehension
- Export to excel and Import from excel add options to background process
- OAuth2 Client Credentials
- AuthApi Controller
- Maybe will adopt CQRS
Build with
Describes which version .
Name | Version |
---|---|
NestJs | v9.x |
NodeJs | v18.x |
Typescript | v4.x |
Mongoose | v6.x |
MongoDB | v6.x |
PostgreSQL | - |
Yarn | v1.x |
NPM | v8.x |
Docker | v20.x |
Docker Compose | v2.x |
Swagger | v6.x |
Objective
- Easy to maintenance
- NestJs Habit
- Component based folder structure
- Repository Design Pattern or Data Access Layer Design Pattern
- Support Microservice Architecture, Clean Architecture, and/or Hexagonal Architecture
- Follow The Twelve-Factor App
- Adopt SOLID and KISS principle
Features
- NestJs v9.x π₯³
- Typescript π
- Production ready π₯
- Swagger included
- Authentication and authorization (
JWT
,API Key
) πͺ - Role management system
- Storage integration with
AwsS3
- Upload file
single
andmultipart
to AwsS3 - Support multi-language
i18n
π£ - Request validation with
class-validation
- Serialization with
class-transformer
- Url Versioning
- Server Side Pagination, there have 3 of types
- Import and export data with excel by using
decorator
Database
- MongoDB integrate by using mongoose π
- PostgreSQL integrate by using typeorm π (Ongoing)
- Multi Database
- Database Transaction
- Database Soft Delete
- Database Migration
Logger and Debugger
- Logger
Morgan
and DebuggerWinston
π
Security
- Apply
helmet
,cors
, andrate-limit
- Timeout awareness and can override βοΈ
- User agent awareness, and can whitelist user agent
Setting
- Support environment file
- Centralize configuration π€
- Centralize response
- Centralize exception filter
- Setting from database πΏ
- Maintenance mode on / off from database π€
Others
- Support Docker Installation
- Support CI/CD with Github Action or Jenkins
- Husky GitHook For Check Source Code, and Run Test Before Commit πΆ
- Linter with EsLint for Typescript
Prerequisites
We assume that everyone who comes here is programmer with intermediate knowledge
and we also need to understand more before we begin in order to reduce the knowledge gap.
- Understand NestJs Fundamental, Main Framework. NodeJs Framework with support fully TypeScript.
- UnderstandTypescript Fundamental, Programming Language. It will help us to write and read the code.
- Understand ExpressJs Fundamental, NodeJs Base Framework. It will help us in understanding how the NestJs Framework works.
- Understand what NoSql is and how it works as a database, especially MongoDB.
- Understand Repository Design Pattern or Data Access Object Design Pattern. It will help to read, and write the source code
- Understand The SOLID Principle and KISS Principle for better write the code.
- Optional. Understand Microservice Architecture, Clean Architecture, and/or Hexagonal Architecture. It can help to serve the project.
- Optional. Understanding The Twelve Factor Apps. It can help to serve the project.
- Optional. Understanding Docker. It can help to run the project.
Getting Started
Before we start, we need to install some packages and tools. The recommended version is the LTS version for every tool and package.
Make sure to check that the tools have been installed successfully.
Clone Repo
Clone the project with git.
git clone https://github.com/andrechristikan/ack-nestjs-boilerplate.git
Install Dependencies
This project needs some dependencies. Let's go install it.
yarn install
Create environment
Make your own environment file with a copy of env.example
and adjust values to suit your own environment.
cp .env.example .env
Database Migration
Mongodb. If you want to implement
database transaction
, we must run mongodb as aReplication Set
.
Database migration used NestJs-Command
For migrate
yarn migrate
For rollback
yarn rollback
Test
The automation is still not good net. I'm still lazy too do that.
The project provide 3 automation testing unit testing
, integration testing
, and e2e testing
.
yarn test
For specific test use this
-
Unit testing
yarn test:unit
-
Integration testing
yarn test:integration
-
E2E testing
yarn test:e2e
Run Project
Finally, Cheers π»π» !!! we passed all steps.
Now we can run the project.
yarn start:dev
Run Project with Docker
docker-compose up -d
API Reference
We have already provided the API reference. To visit, click here.
Environment
Detail information about the environment
APP Environment
Key | Type | Description |
---|---|---|
APP_NAME | string |
Application name |
APP_ENV | string |
|
APP_LANGUAGE | string |
Enum languages, separator , |
HTTP Environment
Key | Type | Description |
---|---|---|
HTTP_HTTP_ENABLE | boolean |
Application Http on/off |
HTTP_HOST | string |
Application host serve |
HTTP_PORT | number |
Application port serve |
HTTP_VERSIONING_ENABLE | boolean |
Application url versioning on/off |
HTTP_VERSION | number |
Application url version number. When HTTP_VERSIONING_ENABLE is enabled, the application version number is used. |
Debugger Environment
Key | Type | Description |
---|---|---|
DEBUGGER_HTTP_WRITE_INTO_FILE | boolean |
Http debugger write into file |
DEBUGGER_HTTP_WRITE_INTO_CONSOL | boolean |
Http debugger write into console |
DEBUGGER_SYSTEM_WRITE_INTO_FILE | boolean |
System debugger write into file |
DEBUGGER_SYSTEM_WRITE_INTO_CONSOLE | boolean |
System debugger write into console |
Middleware Environment
Key | Type | Description |
---|---|---|
MIDDLEWARE_TIMESTAMP_TOLERANCE | string |
Tolerance timestamp and used for validate the ApiKey . ms package value |
MIDDLEWARE_TIMEOUT | string |
Request timeout. ms package value |
Documentation Environment
Key | Type | Description |
---|---|---|
DOC_NAME | string |
Documentation tittle |
DOC_VERSION | number |
Documentation version |
Job Environment
Key | Type | Description |
---|---|---|
JOB_ENABLE | boolean |
Application Job or Schedule turn on/off |
Database Environment
Key | Type | Description |
---|---|---|
DATABASE_HOST | string |
Mongodb URL. Support standard url , replication , or srv |
DATABASE_NAME | string |
Database name |
DATABASE_USER | string |
Database user |
DATABASE_PASSWORD | string |
Database user password |
DATABASE_DEBUG | boolean |
Trigger database DEBUG |
DATABASE_OPTIONS | string |
Mongodb connect options |
Auth JWT Access Token Environment
Key | Type | Description |
---|---|---|
AUTH_JWT_SUBJECT | setting |
Jwt subject |
AUTH_JWT_AUDIENCE | string |
Jwt audience |
AUTH_JWT_ISSUER | string |
JWT issuer |
AUTH_JWT_ACCESS_TOKEN_SECRET_KEY | string |
Secret access token, free text. |
AUTH_JWT_ACCESS_TOKEN_EXPIRED | string |
Expiration time for access token. ms package value |
Auth JWT Encrypt Access Token Environment
Key | Type | Description |
---|---|---|
AUTH_JWT_ACCESS_TOKEN_ENCRYPT_KEY | string |
Encrypt key for access token payload |
AUTH_JWT_ACCESS_TOKEN_ENCRYPT_IV | string |
Encrypt IV for access token payload |
Auth JWT Refresh Token Environment
Key | Type | Description |
---|---|---|
AUTH_JWT_REFRESH_TOKEN_SECRET_KEY | string |
Secret refresh token, free text. |
AUTH_JWT_REFRESH_TOKEN_EXPIRED | string |
Expiration time for refresh token. ms package value |
AUTH_JWT_REFRESH_TOKEN_REMEMBER_ME_EXPIRED | string |
Expiration time for refresh token when remember me is checked. ms package value |
AUTH_JWT_REFRESH_TOKEN_NOT_BEFORE_EXPIRATION | string |
Token active for refresh token before x time. ms package value |
Auth JWT Encrypt Refresh Token Environment
Key | Type | Description |
---|---|---|
AUTH_JWT_REFRESH_TOKEN_ENCRYPT_KEY | string |
Encrypt key for refresh token payload |
AUTH_JWT_REFRESH_TOKEN_ENCRYPT_IV | string |
Encrypt IV for refresh token payload |
AWS Environment
Key | Type | Description |
---|---|---|
AWS_CREDENTIAL_KEY | string |
AWS account credential key |
AWS_CREDENTIAL_SECRET | string |
AWS account credential secret |
AWS_S3_REGION | string |
AWS S3 Region |
AWS_S3_BUCKET | string |
AWS S3 Name of Bucket |
Api Key Encryption
Please keep the
secret
private.
ApiKeyHashed uses sha256
encryption, and dataObject
encryption is AES256
.
To do the encryption.
-
Make sure we have value of
key
: You can find the key for apiKey in the database.secret
:This value is only generated when the apiKey is created
. After that, if you lose the secret, you need to recreate the apiKey.encryptionKey
: You can find the key for encryption in the database.passphrase
: You can find the secret for encryption in the database. (Actually, is need to be private too. Same withsecret
). This is IV for encrypt AES 256.
-
Concat the
key
andsecret
.const concatApiKey = `${key}:${secret}`;
-
Encryption
concatApiKey
withsha256
const apiKeyHashed = this.helperHashService.sha256(concatApiKey);
-
Then create
dataObject
and put theapiKeyHashed
into itconst dataObject: IAuthApiRequestHashedData = { key, // from 1.key timestamp: this.helperDateService.timestamp(), // ms timestamp hash: apiKeyHashed, // from 3 }
-
Encryption the
dataObject
withAES 256
These data
encryptionKey
, andpassphrase
can be find in database.const passphrase = 'cuwakimacojulawu'; // <--- IV for encrypt AES 256 const encryptionKey = 'opbUwdiS1FBsrDUoPgZdx'; const apiKeyEncryption = await authApiService.encryptApiKey( data, encryptionKey, passphrase );
-
Last, combine the
key
andapiKeyEncryption
const xApiKey = `${key}:${apiEncryption}`;
-
Send into request. Put the
xApiKey
in request headers{ "headers": { "x-api-key": "${xApiKey}", ... ... ... } }
Adjust Mongoose Setting
Optional, if your mongodb version is < 5
Go to file src/common/database/services/database.options.service.ts
and add useMongoClient
to mongooseOptions
then set value to true
.
const mongooseOptions: MongooseModuleOptions = {
uri,
useNewUrlParser: true,
useUnifiedTopology: true,
serverSelectionTimeoutMS: 5000,
useMongoClient: true
};
License
Distributed under MIT licensed.