Boilerplate codes to build Restful API in NodeJS
- Getting Started
- Tech Stack
- Packages Used
- S/W Architecture
- Examples
- Code Generation
- What's Next?
- Authors
- License
Install latest Node.js LTS https://nodejs.org/en/download/package-manager/
- Debian
sudo apt update
sudo apt install nodejs
nodejs -v
- Windows
choco install nodejs-lts
node --version
Install PostgreSQL DB
- Debian
sudo apt install postgresql
- Windows
choco install postgresql
# git clone will create a directory named myAppName
# if the directory is already created, then use .(dot) instead of myAppName
git clone https://github.com/junekimdev/boilerplate-node-api.git <myAppName>
cd myAppName
yarn
# remove .git directory beforehand
git init
git add .
git commit -m "Initial commit"
git branch -M master
git remote add origin <myGitRepo>
git push -u origin master
Example:
#NODE_ENV=production
SERVICE_NAME=myservice
PORT=3000
CORS_ORIGIN=http://localhost:3000
#TRUST_PROXY=172.17.0.0/16
# DB
PGHOST=localhost
PGUSER=myservice
PGDATABASE=myservicedb
PGPASSWORD=securepassword
PGPORT=5432
DB_POOL_MAX=20
DB_IDLE_TIMEOUT=30000
DB_CONN_TIMEOUT=2000
# Upload directory from the project root
UPLOAD_ROOT=/data/upload
PUBLIC_PROFILE_DIR=/images/profiles # within public directory
# JWT
JWT_PRI_FILENAME=es256_prv.pem
JWT_PUB_FILENAME=es256_pub.pem
JWT_ISS=jrn;;;auth;https://mycompany.com/auth
#VAPID
VAPID_SUBJECT=mailto:[email protected] # this should be url or mailto
#VAPID_PUB_KEY=
#VAPID_PRI_KEY=
Modify init.sql
file to your liking except some SQLs between REQUIRED
psql -f init.sql
- Backend language: Typescript(Javascript)
- API documentation standard: openapi 3.0.3
- Database: PostgreSQL
- Access control: Basic Authorization & Bearer Authorization (RFC 7235)
- Basic authorization scheme: email(which is username) and password as in RFC 7617
- Bearer authorization scheme: JWT as in RFC 6750
- Token signing algorithm: ES256, which is ECDSA using P-256 and SHA256
- Public & private key format: PEM
- Password hash algorithm and encoding: SHA256 with Base64 encoding
- WebAPIs: Push API
- JS engine: node.js
- API engine: express.js
- Body-parse middleware: express.js built-ins
- multipart/form-data parser: busboy
- header middleware: helmet.js
- CORS middleware: cors
- Logging middleware: pino.js
- DBMS (for PostgreSQL): pg
- Environmental variable loader: dotenv
- Access-token (for JWT): jsonwebtoken
- Push-notification: web-push
- Unit Test: jest
- Integration Test: jest & supertest
root/
├── package.json
├── .env
├── project_files
├── public/
│ └── static_files
├── doc/
| ├── openapi.yaml
│ └── document_files
├── keys/
│ └── key_files
├── src/
│ ├── server.ts
│ ├── errorHandler.ts
│ ├── api/
│ │ ├── index.ts
│ │ └── v1.ts
│ ├── middleware/
│ │ ├── basicAuth.ts
│ │ ├── bearerAuth.ts
│ │ ├── data_validator_files
│ │ └── access_control_files
│ ├── services/
│ │ └── eachService/
│ │ ├── index.ts
│ │ ├── apiHandler.ts
│ │ ├── provider.ts
│ │ └── types.ts
│ └── utils/
│ ├── errors.ts
│ └── utility_files
└── test/
├── test.config
├── initTest.ts
├── testData.sql
├── unit/
│ ├── eachService/
│ │ ├── handler.test.ts
│ │ └── provider.test.ts
│ └── unit_test_files
├── integration/
│ └── integration_test_files
└── coverage/
└── test_coverage_report_files
/public
serves static files/doc
serves documents for the project/doc/openapi.yaml
is API document according to OpenAPI 3.x Spec/src
serves source codes of the API server/src/server.ts
is the entry file for the server- This sets up all middlewares
- This has the central error handler
/src/api/index.ts
selects API version and provides root router/src/api/v1.ts
provides routing logic in the said version- This connects API paths to services
/src/middleware/basicAuth.ts
is the basic authorization middleware- This sets
userId
andemail
inreq.locals
- This sets
/src/middleware/bearerAuth.ts
is the bearer authorization middleware- This sets decoded
accessToken
inreq.locals
- This sets decoded
/services
holds services, which processes business logic/services/eachService
should have descriptive names that clearly says what it does- Recommended format:
verb + noun
- CRUD verbs are great
- Recommended format:
/services/eachService/index.ts
decouples inside from outside/services/eachService/apiHandler.ts
handles requests- This MUST do:
- extracts data out of request
body
/param
/query
- extracts data out of request
locals
passed by middleware - validates data
- calls provider to process the data
- decides which HTTP status will send (REST API)
- decides which error to throw
- try-catch all internal errors and pass them to the central error handler
- extracts data out of request
- This MUST do:
/services/eachService/provider.ts
provides the core of service by processing business logic- This MAY do:
- interacts with DB or network to process data
- executes another file to process data such as python files, golang files, etc.
- This MAY do:
/services/eachService/types.ts
provides definitions of type that need for the service- This MAY have:
IReqBody
,IReqParam
,IReqQuery
,IReqLocals
,IResBody
, etc.
- This MAY have:
/src/utils
holds utility files that are used across the project/src/utils/errors.ts
defines:class AppError
that extendsError
classerrDef
object that holds pre-defined error descriptions ordered by status numbercode
property inerrDef
object- is Error-Identification-Code that you maintain within your organization
- can be used for analytics and for informing client
node codegen.js -name=servicename
This will create files according to the architecture explained above
node keygen-es256.js -name=keyname
This will create a ES256 key pair to be used
# Required web-push installed
node keygen-vapid.js
This will append a VAPID key pair in .env
file
- Add Redis as a cache layer to implement cache-first fetching strategy
- Add node-cron as a scheduler to execute timed tasks
- June Kim - Initial work - Github
This project is licensed under the MIT License - see the LICENSE file for details