Skip to content

Repository files navigation

Node-Boot Fastify Sample

A comprehensive sample Node-Boot application using Fastify framework that demonstrates best practices for building scalable TypeScript applications with dependency injection, validation, persistence, and more.

🚀 Quick Start

Prerequisites

  • Node.js (LTS version recommended)
  • pnpm (package manager)
  • SQLite (for local development)

Installation & Setup

  1. Clone and install dependencies:

    git clone https://github.com/nodejs-boot/sample-fastify.git
    cd sample-fastify
    pnpm install
  2. Start development server:

    pnpm star
    #or with nodemon for hot reload
    pnpm dev

run

  1. Access the application:

  2. Actuator Endpoints:

    • /actuator/health - Application health status
    • /actuator/info - Application info
    • /actuator/git - Git info
    • /actuator/config - Current configuration
    • /actuator/metrics - Application metrics
    • /actuator/prometheus - Prometheus metrics
    • /actuator/controllers - Registered controllers
    • /actuator/interceptors - Registered interceptors
    • /actuator/middlewares - Registered middlewares

📋 Available Scripts

ScriptDescription
pnpm startBuild and start production server
pnpm start:prodBuild and start with NODE_ENV=production
pnpm devStart development server with hot reload
pnpm buildCompile TypeScript to JavaScript
pnpm postbuildRun Node-Boot AOT (Ahead of Time) compilation
pnpm clean:buildRemove dist directory
pnpm lintRun ESLint
pnpm lint:fixRun ESLint with auto-fix
pnpm formatCheck code formatting
pnpm format:fixFormat code with Prettier
pnpm testRun tests with Jest
pnpm typecheckType check without compilation
pnpm nodeboot:updateUpdate Node-boot framework - Update all @nodeboot packages
pnpm rebuild:sqliteRebuild SQLite native bindings
pnpm create:migrationCreate new TypeORM migration

⚙️ Configuration

The application uses YAML-based configuration with environment overrides:

Configuration Files

  • app-config.yaml - Main application configuration
  • app-config.local.yaml - Local development overrides
  • app-credentials.local.yaml - Local credentials (git-ignored)

Key Configuration Sections

app:
name: "fast-service"platform: "node-boot"environment: "development"port: 3000api:
routePrefix: "/api"validations:
enableDebugMessages: truestopAtFirstError: trueserver:
cors:
origin: "*"methods: ["GET", "POST"]

🏗️ Project Structure

src/
├── app.ts # Main application class with decorators
├── server.ts # Application entry point
├── auth/ # Authentication & authorization
├── clients/ # HTTP clients for external services
├── config/ # Configuration classes
├── controllers/ # REST API controllers
├── exceptions/ # Custom exception handlers
├── interfaces/ # TypeScript interfaces
├── middlewares/ # Custom middleware
├── models/ # DTOs and data models
├── persistence/ # Database layer
│ ├── entities/ # TypeORM entities
│ ├── repositories/ # Custom repositories
│ ├── migrations/ # Database migrations
│ └── listeners/ # Entity event listeners
└── services/ # Business logic services

🧩 Code Architecture

App Class

Main application class with feature decorators:

@EnableDI()// Enable Dependency Injection
@EnableOpenApi()// Enable OpenAPI (Swagger) documentation
@EnableSwaggerUI()// Enable SwaggerUI 
@EnableAuthorization()// Enable Authorization
@EnableActuator()// Enable Actuator (health, metrics)
@EnableRepositories()// Enable persistence with TypeORM, transactions, migrations, listeners
@EnableScheduling()// Enable scheduled tasks
@EnableHttpClients()// Enable declarative HTTP clients
@EnableValidations()// Enable request/response validations
@EnableComponentScan()// Enable component scanning with AOT supportexportclassSampleAppimplementsNodeBootApp{start(): Promise<NodeBootAppView>{returnNodeBoot.run(FastifyServer);}}

Controllers

REST API endpoints using decorators for routing and validation:

@Controller("/users","v1")exportclassUsersController{
@Get("/")asyncgetUsers(): Promise<User[]>{returnthis.userService.findAllUser();}}

Key Features:

  • Automatic route registration
  • Built-in validation
  • Swagger documentation generation
  • Exception handling

Services

Business logic layer with dependency injection:

@Service()exportclassUserService{constructor(privatereadonlyuserRepository: UserRepository,privatereadonlylogger: Logger){}}

Key Features:

  • Singleton instances
  • Constructor injection
  • Transaction support with @Transactional
  • Logging integration

Persistence Layer

Entities

TypeORM entities for database mapping:

@Entity()exportclassUser{
@PrimaryGeneratedColumn()id: number;
@Column()email: string;}

Repositories

Node-Boot Data repositories extending TypeORM Repository:

@DataRepository(User)exportclassUserRepositoryextendsRepository<User>{// Custom query methods}

Key Features:

  • Automatic transaction management
  • Custom naming strategies
  • Entity event listeners
  • Migration support

Models & DTOs

Data Transfer Objects with validation and OpenAPI metadata:

@Model()exportclassCreateUserDto{
@IsEmail()email: string;
@IsString()
@MinLength(8)password: string;}

Middlewares

Custom middleware for cross-cutting concerns:

  • LoggingMiddleware - Request/response logging
  • CustomErrorHandler - Global error handling

Configuration Classes

Type-safe configuration with @ConfigurationProperties:

@ConfigurationProperties("app")exportclassAppConfigProperties{name: string;port: number;environment: string;}

🔧 Node-Boot Features Enabled

The application demonstrates various Node-Boot starters and features:

FeatureDecoratorDescription
Dependency Injection@EnableDITypeDI container integration
OpenAPI@EnableOpenApiAutomatic API documentation
Swagger UI@EnableSwaggerUIInteractive API explorer
Authorization@EnableAuthorizationRole-based access control
Actuator@EnableActuatorHealth checks and metrics
Persistence@EnableRepositoriesTypeORM integration + Transactions management
Scheduling@EnableSchedulingCron jobs and scheduled tasks
HTTP Clients@EnableHttpClientsDeclarative HTTP clients
Validations@EnableValidationsRequest/response validation
Component Scan@EnableComponentScanAOT compilation support

🐛 Development

Hot Reload

Development server uses nodemon for automatic restarts:

// nodemon.json
{
"watch": ["src"],
"ext": "ts,json,yaml",
"exec": "ts-node src/server.ts"
}

Database

  • Development: SQLite database (fastify-sample.db)
  • Migrations: Use pnpm create:migration to create new migrations and then add the @Migration decorator to the generated migration class.
  • Seeding: Initial users loaded via users.init.ts

🗄️ Database Configuration

Default Setup (SQLite)

The sample uses SQLite by default for simplicity and portability. The database file (fastify-sample.db) is created automatically in the project root.

Switching to Other Databases

The Node-Boot starter persistence package supports all TypeORM-compatible databases. You can easily switch by updating your configuration:

Supported Databases

  • SQL Databases: PostgreSQL, MySQL, MariaDB, SQLite, Microsoft SQL Server, Oracle, CockroachDB
  • NoSQL Databases: MongoDB

Configuration Steps

  1. Install the appropriate database driver:

    # PostgreSQL
    pnpm add pg
    pnpm add -D @types/pg
    # MySQL/MariaDB
    pnpm add mysql2
    # MongoDB
    pnpm add mongodb
    # SQL Server
    pnpm add mssql
    # Oracle
    pnpm add oracledb
  2. Update your configuration file (app-config.yaml or app-config.local.yaml):

    SQLite Example (default):

    persistence:
    type: "better-sqlite3"synchronize: false # False, meaning that the application rely on migrationscache: truemigrationsRun: truebetter-sqlite3:
    database: "fastify-sample.db"transactions:
    # Controls how many hooks (`commit`, `rollback`, `complete`) can be used simultaneously.# If you exceed the number of hooks of same type, you get a warning. This is a useful to find possible memory leaks.# You can set this options to `0` or `Infinity` to indicate an unlimited number of listeners.maxHookHandlers: 10# Controls storage driver used for providing persistency during the async request timespan.# You can force any of the available drivers with this option.# By default, the modern AsyncLocalStorage will be preferred, if it is supported by your runtime.storageDriver: "AUTO"

    PostgreSQL Example:

    persistence:
    type: "postgres"synchronize: false # False, meaning that the application rely on migrationscache: truemigrationsRun: truepostgres:
    host: "localhost"port: 5432username: "your_username"password: "your_password"database: "your_database"

    MySQL Example:

    datasource:
    type: "mysql"synchronize: false # False, meaning that the application rely on migrationscache: truemigrationsRun: truemysql:
    host: "localhost"port: 3306username: "root"password: "password"database: "fastify_sample"

    MongoDB Example:

    persistence:
    type: "mongodb"cache: falsemongodb:
    database: "facts"#url: mongodb://localhost:27017/?directConnection=trueurl: mongodb+srv://${DATABASE_CREDS}@db-name.mongodb.net/?retryWrites=true&w=majority&appName=sample-fastify
  3. Environment-specific Configuration: Use app-config.local.yaml for local development or app-credentials.local.yaml for sensitive credentials:

    # app-credentials.local.yaml (git-ignored)postgres:
    username: "your_username"password: "your_password"

Production Configuration

For production environments, use environment variables or secure configuration management:

mysql:
username: "${DB_USERNAME}"password: "${DB_PASSWORD}"host: "${DB_HOST:localhost}"port: "${DB_PORT:5432}"database: "${DB_NAME}"

Database Features

The Node-Boot starter persistence package provides:

  • Automatic Connection Management - Connections are managed automatically
  • Transaction Support - Use @Transactional decorator for transaction management
  • Migration System - TypeORM migrations with Node-Boot decorators
  • Entity Event Listeners - Lifecycle hooks for entities
  • Repository Pattern - Custom repositories with @DataRepository
  • Connection Pooling - Built-in connection pool management

Migration Commands

# Create new migration
pnpm create:migration

Note: After creating the migration class, add the @Migration decorator to the generated class to register it. Build and run the application to execute pending migrations at bootstrap.

Example migration class:
import{MigrationInterface,QueryRunner}from"typeorm";import{Migration}from"@nodeboot/starter-persistence";
@Migration()exportclassMigration1701786331338implementsMigrationInterface{asyncup(queryRunner: QueryRunner): Promise<void>{awaitqueryRunner.query(`ALTER TABLE "nb-user" ADD COLUMN "name" varchar(255)`);}asyncdown(queryRunner: QueryRunner): Promise<void>{awaitqueryRunner.query(`ALTER TABLE "nb-user" DROP COLUMN "name"`);}}

Learn More

For detailed database configuration options, visit the Node-Boot Starter Persistence.

Testing

  • Framework: Jest with SWC compiler
  • Configuration:jest.config.js
  • Run tests:pnpm test

Code Quality

  • Linting: ESLint with TypeScript rules
  • Formatting: Prettier with import organization
  • Type Checking: Strict TypeScript configuration

📁 Key Files

  • app.ts - Main application bootstrap with feature decorators
  • server.ts - Application entry point
  • package.json - Dependencies and scripts
  • tsconfig.json - TypeScript configuration
  • app-config.yaml - Application configuration
  • Dockerfile - Container configuration

🚀 Production Deployment

  1. Build the application:

    pnpm build
  2. Start production server:

    pnpm start:prod
  3. Docker deployment:

    • Build docker image
    docker build -f Dockerfile -t fastify-sample .
    • Run docker image
    docker run --rm -it -p 3000:3000 fastify-sample
    • Check container filesystem
    docker run -t -i fastify-sample /bin/sh

API Explorer (Swagger UI)

Access the interactive API documentation at: http://localhost:3000/docs

swagger ui

📚 Learn More

About

Sample Node-Boot app using Fastify

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages