Boilerplate for NodeJS Express Projects written in Typescript
The purpose of this template repository is to fast track APIs development and reach to production ASAP.
At most places except TSOA, there is very less use of external dependency injection or similar libraries to demonstrate how same thing can be achieved in vanilla code. The advantage of this is more control on behavior of dependency injection.
It is designed keeping SOLID Principles
and Loose Coupling
in mind. It demonstrates use of Singleton (like db, auth etc), Factory(cache), Strategy(injecting dependency based on .env like DB_TYPE) design patterns at multiple places.
- Controllers written using TSOA library
- Controllers, Services, Middlewares, Entities, Error handlers all are pre-configured with standard best practices and follows SOLID Principles, loose coupled Architecture
- Mongo Database with extensible database interface for other Databases implementation
- Redis Persistent Queue with extensible interface for other Queues implementation
- NodeCache and RedisCache support with extensible interface for other Cache implementation
- Rust Web assembly boilerplate for compute intensive tasks
- Worker pool for running compute intensive tasks in worker threads
- Standard utilities for validation, email sender are available
- Automatic Swagger generation - combined swagger is generated from swagger docs and tsoa generated swagger specs
- Eslint and Prettier configured for Code quality checks
- Husky configured to run pre commit git hooks to run code quality checks
src/index.ts
This is entry point of project when we donpm start
.src/controllers
This serves as entrypoint of different APIssrc/auth
This contains extensible Auth interface and JWT Auth Implementation for that interfacesrc/middlewares
This contains middlewares that are executed before reaching code flow to controllerssrc/errors
Custom error typessrc/db
This contains extensible Database interface and MongoDB implementationsrc/models
This contains model validation using mongoose schema. Mostlytsoa
is capable of doing basic validation based on type but sometimes we need some conditional validation logic and we need custom validators.src/configs
This contains configuration filessrc/entities
This contains entity cum repository classes. Repository methods are implemented in Entities itself as static methodssrc/services
This is executed from controllers and contains main business logic for each APIsrc/types
This contains types of different objects used across applicationsrc/typings
This extends express namespace for custom properties in request/responsesrc/utils
This contains common utilitiessrc/workers
This implements workerpool and worker tasks to execute in worker threadssrc/p_queue
This contains extensible Persistent Queue interface and Redis Pub/Sub implementationsrc/cache
This contains extensible application cache and Implementation of Node Cache and Redis Cache demonstrating factory patternsrc/__tests__
This contains unit and integration test casesrust-wasm-libs
This contains web assembly code for simple factorial examplekeys
This contains blankprivateKey.pem
andpublicKey.pem
used by JWT auth implementation. One needs to put actual RSA keys in those files before running the application or test cases.Dockerfile
To dockerize the applicationDockerfile.rust-wasm
To dockerize the application with Rust and other dependencies if rust web assembly is usedswagger.json
Generated fromtsoa
and Swagger comments in the code.env
This contains environment variables referred in the codetsoa.json
Configuration file fortsoa
tsconfig.json
Configuration file for typescriptjest.config.ts
Configuration file forJest Test Runner
- NodeJs >= v22.12.0
Install npm modules:
npm install
Rust web assembly code is written in rust-wasm-libs
directory. To compile wasm package Run:
npm run build-rust-wasm
If not using rust web assembly, remove rust-wasm-libs
from package.json
and run npm install
again.
Start application:
npm start
To Run with different env file (e.g. .env.local
):
ENV_FILE=.env.local npm start
To run test cases:
ENV_FILE=.env.test npm run test
Only NodeJS without rust wasm:
docker build . -t <image-repo>/<image-tag> --platform linux/amd64
With rust wasm:
docker build . -f Dockerfile.rust-wasm -t <image-repo>/<image-tag> --platform linux/amd64
To use src/workers/factorial.ts
(rust wasm) - use following snippet into src/routes/app.ts
// Imports
import { createOrGetPool } from "../workers/workerPool.js";
import { Promise as WorkerPromise } from "workerpool";
// Wasm Route
app.get("/wasm/:n", async (req: Request, res: Response) => {
try {
const factorial = await createOrGetPool({
workerFileName: "factorial"
})
.exec("factorial", [req.params.n])
.timeout(10000);
return res.OK(factorial.toString());
} catch (err) {
logger.error(`Error occurred in ${req.path}: %o`, err);
if (err instanceof WorkerPromise.TimeoutError) {
return res.BAD_REQUEST("Operation timeout because of large input. Try smaller input");
}
return res.INTERNAL_SERVER_ERROR((err as Error).message);
}
});
rm -rf rust-wasm-libs src/workers/factorial.ts Dockerfile.rust-wasm
Delete "rust-wasm-libs": "file:rust-wasm-libs/pkg"
dependency and build-rust-wasm
task from package.json
file.