Skip to content

Architecture

DolphJS offers a highly structured, scalable architecture. It builds upon the Express.js ecosystem but introduces paradigms commonly found in robust enterprise frameworks like Spring Boot and NestJS.

DolphJS supports two distinct architectural patterns. While you can mix them, the Component-based Pattern is strongly recommended for modern applications.

This pattern leverages TypeScript decorators and Dependency Injection (DI) to automate wiring.

In this pattern:

  1. Controllers define routes and handle HTTP requests.
  2. Services execute business logic and database interactions.
  3. Components encapsulate Controllers and Services into modules.
  4. DolphFactory reads the components, resolves dependencies, and boots the application.
import { Component } from '@dolphjs/dolph/decorators';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
// The Component acts as a DI container for this feature module
@Component({ controllers: [AuthController], services: [AuthService] })
export class AuthComponent {}

For developers migrating legacy Express applications or those who prefer manual routing, DolphJS offers the DolphRouteHandler.

import { DolphRouteHandler } from '@dolphjs/dolph/classes';
import { Dolph } from '@dolphjs/dolph/common';
import { Router } from 'express';
export class AuthRouter extends DolphRouteHandler<Dolph> {
path = '/auth';
router = Router();
constructor() {
super();
this.initRoutes();
}
private initRoutes() {
this.router.post(`${this.path}/login`, (req, res) => {
res.send('Login');
});
}
}

Understanding how DolphJS boots up is crucial for debugging and advanced configuration.

  1. Configuration Loading: The DolphFactory reads dolph_config.yaml.
  2. Middleware Binding: Global middlewares (CORS, Helmet, Body Parsers) are attached to the underlying Express instance.
  3. Database Connection: If configured, DolphJS establishes connections to MongoDB or MySQL.
  4. Dependency Injection: The framework scans all registered @Component classes. It instantiates Services as singletons and injects them into Controllers.
  5. Route Registration: The framework scans Controller decorators (@Route, @Get, etc.) and maps them to Express routes, wrapping them in asynchronous try-catch blocks automatically.
  6. Server Start: The HTTP server begins listening on the configured port.

DolphJS uses a constructor-based injection model mapped through the @Component decorator.

When you define a controller:

@Route('users')
export class UserController extends DolphControllerHandler<Dolph> {
// Notice this is NOT passed in the constructor.
// DolphJS reflects the type and injects it automatically at runtime.
private userService!: UserService;
}

The DI container ensures that exactly one instance of UserService exists, promoting memory efficiency and making it easy to share state across the application if needed.