Boilerplate/Sample project for NestJS CRUD API in Node.js and Typescript
Go to file
2023-04-25 01:26:47 +08:00
.vscode temp commit, not functioning 2023-04-20 23:18:31 +08:00
data add gitkeep for data folder 2023-04-17 11:02:02 +08:00
image_files/fsroot Initial commit 2023-04-17 10:20:39 +08:00
src Add ZGC 2023-04-25 01:26:47 +08:00
test Initial commit 2023-04-17 10:20:39 +08:00
thunder-tests Add ZGC 2023-04-25 01:26:47 +08:00
.dockerignore Initial commit 2023-04-17 10:20:39 +08:00
.eslintrc.js Initial commit 2023-04-17 10:20:39 +08:00
.gitignore Ignore package-lock.json due to yarn 2023-04-17 22:14:44 +08:00
.gitlab-ci.yml Initial commit 2023-04-17 10:20:39 +08:00
.prettierrc Initial commit 2023-04-17 10:20:39 +08:00
docker-compose.db.yml temp commit, not functioning 2023-04-20 23:18:31 +08:00
docker-compose.yml Initial commit 2023-04-17 10:20:39 +08:00
Dockerfile Initial commit 2023-04-17 10:20:39 +08:00
Dockerfile.dev Initial commit 2023-04-17 10:20:39 +08:00
nest-cli.json Initial commit 2023-04-17 10:20:39 +08:00
package.json Add Mongo 2023-04-23 22:04:03 +08:00
README.md temp commit, not functioning 2023-04-20 23:18:31 +08:00
sample.env-app Initial commit 2023-04-17 10:20:39 +08:00
sample.env-docker-compose Initial commit 2023-04-17 10:20:39 +08:00
tsconfig.build.json temp commit, not functioning 2023-04-20 23:18:31 +08:00
tsconfig.json temp commit, not functioning 2023-04-20 23:18:31 +08:00
yarn.lock Add Mongo 2023-04-23 22:04:03 +08:00

Basic Nestjs Application/API Boilerplate project with Git CI

This project is based on the Basic Docker Project with Git CI project and include:

  1. Node.js + Nestjs framework + Typescript + Swagger + JSON Logging (Shellscript + Winston)
  2. This project is based on the new project generated by nest new <project> command (as of 2023-03-24)
  3. Two dockerfile for production and development (which will be supported by .gitlab-ci.yml)
  4. Dockerfile using multiple-stage builds
  5. docker-compose setup for local development
  6. Minimal API implementation (version, healthcheck)

Local development using docker-compose and attach with VSCode

Preparation

Assume you are using Linux (Mac or WSL2) and your login user id is 1000

  1. Clone the project
  2. Prepare the .env (for docker-compose) and .env-app (for Node.js app) files
  3. Refer to sample.env-* for the details
  4. Create data folder (for vscode-server which will be running inside the container for VSCode) mkdir -p ./data/vscode-server
  5. The VSCode extension and some required data will be saved in this persistence folder.
  6. If you have started the service before making the directory (under your user account), you may get error when you attach VSCode. To resolve it, change the data and vscode-server folder ownership to you.
  7. Build the image docker-compose build

Start the environment as a dummy-daemon service

Assume you have installed docker extension in VSCode

docker-compose up -d

Attach container with VSCode

  1. Start the service (if not yet)
  2. Start VSCode and locate Docker in the left tab panel, click the docker icon
  3. Locate the running container of your application (e.g. basic-nestjs-app)
  4. Right-click the container instance, select Attach Visual Studio Code
  5. From the dropdown menu, select the instance again
  6. A new VSCode Window will be shown if success
  7. If it is the first time, please pick the working folder to /home/node/app

Run the server application

  1. In the VSCode terminal (within the container), type yarn start or yarn start:dev
  2. To use the VSCode debugger, click the debug and launch the Debug Nest Framework (See launch.json) for details

Databases

This project requires connecting to the database (MySQL, MongoDB). There are docker-compose files contain the database service.

Standalone DB service

If you try this project with the local Node.js environment, you can use standalone database service which provided by the docker-compose.db.yml.

It comes with these service:

  1. MySQL/MariaDB server
  2. Adminer - MySQL Web GUI Client
  3. MonogoDB server
  4. Monogo Express Web GUI Client

Use the following command to manage the docker services/stack:

# To start the service as daemon
docker-compose -f docker-compose.db.yml up -d

# To stop and down the service (and network resources)
docker-compose -f docker-compose.db.yml down

Adminer

Adminer is the Web GUI for MySQL/Mariadb. Once the docker-compose.db.yml is started, you may access it by:

http://localhost:33306

Mongo Express

Mongo Express is the Web GUI for MongoDB. Once the docker-compose.db.yml is started, you may access it by:

http://localhost:32017

Troubleshooting

Port binding issue

In WSL2 environment, you may get the following error sometime:

Error response from daemon: Ports are not available: exposing port TCP 0.0.0.0:3306 -> 0.0.0.0:0: listen tcp 0.0.0.0:3306: bind: An attempt was made to access a socket in a way forbidden by its access permissions.

First of all, you can check if there is stopped container that occupied the port, you can use the prune command to clean up the container:

docker container prune

NOTE:

In this project, we change the exposed ports to high-port, not low-port like 3306.

Sometime, Windows firewall will block the port/port-range. It can be checked and add a rule via Powershell

# Check if 3306 is excluded:
netsh int ipv4 show excludedportrange protocol=tcp

# Add excluded range/port: (Need to run-as admin)
netsh int ipv4 add excludedportrange protocol=tcp startport=3306 numberofports=1
# 


Swagger

The Nest Swagger framework is added into this project. For details, please see Nestjs OpenAPI documentation.

When the is started and either NODE_ENV is not set to production OR ENABLE_SWAGGER is true, the swagger will be enabled. It can be access via URL: /api. For example: http://localhost:3000/api

About the Winston Logger and Price Service Core

To use the Node.js Logger with Winston and output as a json format (required by Price's K8s best practice), please consider to use Price Service Core's Utility Service for logger.

The Price Service Core has benn installed in this project. This is the command used: yarn add --registry https://repo-manager.price-hk.com/repository/npm-group/ @price/service-core@0.4.0

And a wrapper class WinstonLoggerService (file src/logger/winston.service.ts) is created as well. Logger configration has also implemented in this project too.

To use this, in your TS source code:

  1. import the class. e.g.: import { WinstonLoggerService } from './logger/winston.service';
  2. Set the context in constructor:
    constructor(private logger: WinstonLoggerService) {
      this.logger.setContext(this.constructor.name);
    }
    
  3. Log as needed: this.logger.debug("the message to log");

Working with the sample user-API (CURD)

API-Doc: /api

Note:

  1. The following use Linux cURL command to operate the API.
  2. Header is provided. Especially for POST and PATCH

Create User

curl -X POST -H 'Content-Type: application/json' -d '{ "name": "Tester 1" }' 'http://localhost:3000/users'

List Users

List users (with header outpu):

curl -i 'http://localhost:3000/users'

Formatted result with JQ:

curl -s 'http://localhost:3000/users' | jq

Get specific user

curl -s 'http://localhost:3000/users/0' | jq

Update specific user

curl -X PATCH -H 'Content-Type: application/json' -d '{ "name": "Tester 2" }' 'http://localhost:3000/users/1'

Note: Header must be provided.

Delete specific user

curl -X DELETE 'http://localhost:3000/users/1'