π₯ π
ACK NestJs Boilerplate This repo will representative of authentication service and authorization service
ACK NestJs is a Http NestJs v9.x boilerplate. Best uses for backend service.
You can request feature or report bug with following this link
Other Repo
- Kafka Integration : Microservice (Apache Kafka Integration) OUTDATED
Table of contents
- ACK NestJs Boilerplate
π₯ π
Important
Very limited documentation
- The features will be relate with AWS
- Stateless Authorization
- If you want to implementΒ
database transactions
. You must run MongoDB as aΒreplication set
. - If you want to implementΒ
Google SSO
.- You must have google account, then set your app on
google console
to get theclientId
andclientSecret
.
- You must have google account, then set your app on
- If you change the environment value of
APP_ENV
toproduction
, that will trigger.- CorsMiddleware will implement
src/configs/middleware.config.ts
. - Documentation will
disable
.
- CorsMiddleware will implement
Next Todo
Next development
- Resolve N+1 Problem in
v5.0.0++
- Refactor apikey module, change
x-api-key
to${key}:${secret}
. Free for user to create ApiKey by themself. - Refactor Authorization, optimize
- remove permission entity, make then static permission
- implement acl policy guard
- remember me remove
- role access for to type
- remove permission token
- add policy for each endpoint
- Refactor Unit Testing for common module
- Google SSO for login and sign up
- Refactor Doc or Swagger
- Update Documentation, add behaviors
- Update Documentation, include an diagram for easier comprehension
Build with
Describes which version.
Name | Version |
---|---|
NestJs | v9.4.x |
NodeJs | v18.12.x |
Typescript | v5.0.x |
Mongoose | v7.0.x |
MongoDB | v6.0.x |
Yarn | v1.22.x |
NPM | v8.19.x |
Docker | v20.10.x |
Docker Compose | v2.6.x |
Swagger | v6.3.x |
Objective
- Easy to maintenance
- NestJs Habit
- Component based / modular folder structure
- Stateless authentication and authorization
- Repository Design Pattern or Data Access Layer Design Pattern
- Follow Community Guide Line
- Follow The Twelve-Factor App
- Adopt SOLID and KISS principle
- Support for Microservice Architecture, Serverless Architecture, Clean Architecture, and/or Hexagonal Architecture
Features
Main Features
- NestJs v9.x
π₯³ - Typescript
π - Production ready
π₯ - Repository Design Pattern (Multi Repository, can mix with other orm)
- Swagger / OpenAPI 3 included
- Authentication (
Access Token
,Refresh Token
,API Key
) - Authorization, Role and Permission Management
- Google SSO for Login and Sign Up
- Support multi-language
i18n
π£ , can controllable with request headerx-custom-lang
- Request validation for all request params, query, dan body with
class-validation
- Serialization with
class-transformer
- Url Versioning, default version is
1
- Server Side Pagination
- Import and export data with CSV or Excel by using
decorator
Database
- MongoDB integrate by using mongoose
π - Multi Database
- Database Transaction
- Database Soft Delete
- Database Migration
Logger and Debugger
- Logger with
Morgan
- Debugger with
Winston
π
Security
- Apply
helmet
,cors
, andthrottler
- 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
πΏ
Third Party Integration
- SSO
Google
- Storage integration with
AwsS3
- Upload file
single
andmultipart
to AwsS3
Others
- Support Docker installation
- Support CI/CD with Github Action or Jenkins
- Husky GitHook for run linter before commit
πΆ - Linter with EsLint for Typescript
Behaviors
Ongoing update
Structure
Folder Structure
/app
The final wrapper module/common
The common module/configs
The configurations for this project/health
health check module for every service integrated/jobs
cron job or schedule task/language
json languages/migration
migrate all init data/modules
other modules based on service based on project/router
endpoint router.Controller
will put in this
Module structure
Full structure of module
.
βββ module1
βββ abstracts
βββ constants // constant like enum, static value, status code, etc
βββ controllers // business logic for rest api
βββ decorators // warper decorator, custom decorator, etc
βββ dtos // request validation
βββ docs // swagger or OpenAPI 3
βββ errors // custom error
βββ factories // custom factory
βββ filters // custom filter
βββ guards // guard validate
βββ indicators // custom health check indicator
βββ interceptors // custom interceptors
βββ interfaces
βββ middleware
βββ pipes
βββ repository
βββ entities // database entities
βββ repositories // database repositories
βββ module1.repository.module.ts
βββ serializations // response serialization
βββ services
βββ tasks // task for cron job
βββ module1.module.ts
Response Structure
This section will describe the structure of the response.
Response Default
_metadata useful when we need to give the frontend some information
Default response for the response
export class ResponseMetadataSerialization {
languages: string[];
timestamp: number;
timezone: string;
requestId: string;
path: string;
version: string;
repoVersion: string;
[key: string]: any;
}
export class ResponseDefaultSerialization {
statusCode: number;
message: string;
_metadata?: ResponseMetadataSerialization;
data?: Record<string, any>;
}
Response Paging
_metadata useful when we need to give the frontend some information
Default response for pagination.
export class RequestPaginationSerialization {
search: string;
filters: Record<
string,
string | number | boolean | Array<string | number | boolean>
>;
page: number;
perPage: number;
orderBy: string;
orderDirection: ENUM_PAGINATION_ORDER_DIRECTION_TYPE;
availableSearch: string[];
availableOrderBy: string[];
availableOrderDirection: ENUM_PAGINATION_ORDER_DIRECTION_TYPE[];
}
export class ResponsePaginationSerialization extends RequestPaginationSerialization {
total: number;
totalPage: number;
}
export class ResponsePaginationCursorSerialization {
nextPage: string;
previousPage: string;
firstPage: string;
lastPage: string;
}
export interface ResponsePagingMetadataSerialization
extends ResponseMetadataSerialization {
cursor: ResponsePaginationCursorSerialization;
pagination: ResponsePaginationSerialization;
}
export class ResponsePagingSerialization {
statusCode: number;
message: string;
_metadata: ResponsePagingMetadataSerialization;
data: Record<string, any>[];
}
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 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
To know the details, you can read the documentation. Jump to document section
Test
The project only provide unit testing
.
yarn test
Run Project
Finally, Cheers
Now you can run the project.
yarn start:dev
Run Project with Docker
For docker installation, we need more tools to be installed in our instance.
Then run
docker-compose up -d
After all containers up, we not finish yet. We need to manual configure mongodb as replication set.
In this case primary will be mongo1
-
In root dir, Enter the
mongo1
containerdocker exec -it mongo1 mongosh
-
In mongo1 container, tell the primary to be as replication set
rs.initiate({_id:"rs0", members: [{_id:0, host:"mongo1:27017", priority:3}, {_id:1, host:"mongo2:27017", priority:2}, {_id:2, host:"mongo3:27017", priority:1}]}, { force: true })
will return response
{status: ok}
then exit the container
exit
-
In root dir, adjust env file
... DATABASE_HOST=mongodb://mongo1:27017,mongo2:27017,mongo3:27017 DATABASE_NAME=ack DATABASE_USER= DATABASE_PASSWORD= DATABASE_DEBUG=false DATABASE_OPTIONS=replicaSet=rs0&retryWrites=true&w=majority ...
-
In root dir, Restart the service container
docker restart service
Database Migration
The migration will do data seeding to MongoDB. Make sure to check the value of the
DATABASE_
prefix in your.env
file.
The Database migration used NestJs-Command
For seeding
yarn seed
For remove all data do
yarn rollback
API Reference
You can check The ApiSpec after running this project. here
User Test
- Super Admin
- email:
[email protected]
- password:
aaAA@@123444
- email:
- Admin
- email:
[email protected]
- password:
aaAA@@123444
- email:
- Member
- email:
[email protected]
- password:
aaAA@@123444
- email:
- User
- email:
[email protected]
- password:
aaAA@@123444
- email:
Documentation
Ongoing update
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 // <--- add this
};
License
Distributed under MIT licensed.
Contribute
How to contribute in this repo
-
Fork the project with click
Fork
button of this repo. -
Clone the fork project
git clone "url you just copied"
-
Make necessary changes and commit those changes
-
Commit the changes
git commit -m "your message"
-
Push changes to fork project
git push origin -u main
-
Back to browser, goto your fork repo github. Then, click
Compare & pull request
If your code behind commit with the original, please update your code and resolve the conflict. Then, repeat from number 6.
Rule
- Avoid Circular Dependency
- Consume component based / modular folder structure, and repository design pattern
- Always make
service
for every module is independently. - Do not put
controller
into service modules, cause this will break the dependency. Only put the controller intorouter
and then inject the dependency. - Put the config in
/configs
folder, and for dynamic config put asenvironment variable
CommonModule
only for main package, and put the module that related of service/project into/src/modules
. So, if we want to clear the unnecessary module, we just need to delete thesrc/modules/**
- If there a new service in CommonModule. Make sure to create the unit test in
/unit
.