Skip to content

Components ​

Components are reusable, pluggable modules that encapsulate a group of related features. A component acts as a powerful container for various resources--including providers, services, controllers, repositories, and even entire mini-applications--making it easy to share and integrate complex functionality across projects.

Deep Dive: See Components Reference for detailed implementation patterns, directory structure, and best practices.

What is a Component? ​

A component is a class that extends BaseComponent and is responsible for:

  • Binding Dependencies: Registering services, controllers, repositories, providers, or other resources with the application's dependency injection container.
  • Configuring Features: Setting up middlewares, initializing services, or performing any other setup required for the feature to work.

A single component can bundle everything needed for a specific domain. AuthenticateComponent, for example, carries services for token management, repositories for user data, and controllers for login and signup endpoints. It is a plug-and-play mini-application.

Built-in Components ​

IGNIS includes ready-to-use components for common features. The following are exported from the main barrel (@venizia/ignis):

ComponentDescription
AuthenticateComponentJWT + Basic auth strategies, token services, strategy registry
AuthorizeComponentCasbin-based RBAC, permission mapping, authorize() middleware
HealthCheckComponentGET /health, POST /health/ping, and GET /health/stats when you opt in
ApiReferenceComponentScalar (the default) or Swagger UI for API documentation
RequestTrackerComponentRequest body parsing and the access log

The following components require direct subpath imports:

ComponentImport FromDescription
MailComponent@venizia/ignis/mailNodemailer/Mailgun transporters with queue executors
SocketIOComponent@venizia/ignis/socket-ioSocket.IO server with Redis adapter
StaticAssetComponent@venizia/ignis/static-assetFile upload/download CRUD, MinIO/Disk storage
WebSocketComponent@venizia/ignis/websocketNative WebSocket support

The x-request-id header is not a component feature. RestApplication.registerDefaultMiddlewares() installs it on every application, before initialize() runs.

See the Built-in Components Reference for detailed documentation.

Creating a Simple Component ​

typescript
import {
  BaseApplication,
  BaseComponent,
  BaseRestController,
  Binding,
  controller,
  CoreBindings,
  inject,
  ValueOrPromise,
} from '@venizia/ignis';

// Define a service
class NotificationService {
  send(opts: { message: string }) { /* ... */ }
}

// Define a controller
@controller({ path: '/notifications' })
class NotificationController extends BaseRestController {
  constructor(
    @inject({ key: 'services.NotificationService' })
    private _notificationService: NotificationService
  ) {
    super({ scope: NotificationController.name });
  }
}

// Create the component
export class NotificationComponent extends BaseComponent {
  constructor(
    @inject({ key: CoreBindings.APPLICATION_INSTANCE })
    private _application: BaseApplication,
  ) {
    super({
      scope: NotificationComponent.name,
      initDefault: { enable: true, container: _application },
      bindings: {
        'services.NotificationService': Binding.bind({ key: 'services.NotificationService' })
          .toClass(NotificationService),
      },
    });
  }

  override binding(): ValueOrPromise<void> {
    this._application.controller(NotificationController);
  }
}

Component Lifecycle ​

StageMethodDescription
1. Instantiationconstructor()Component is created. Define default bindings here.
2. Init DefaultsinitDefaultBindings()If initDefault.enable is true, default bindings are registered in the container (only if not already bound).
3. Configurationbinding()Called during startup. Register controllers and additional resources here.

The configure() method is idempotent -- calling it multiple times has no effect after the first call.

Registering a Component ​

Register components in your application's preConfigure method:

typescript
// src/application.ts
export class Application extends BaseApplication {
  preConfigure(): ValueOrPromise<void> {
    this.component(HealthCheckComponent);
    this.component(ApiReferenceComponent);
    this.component(NotificationComponent);
  }
}

Components are bound as singletons automatically when registered via this.component().

Customizing Component Options ​

Most components accept configuration options. Override them before registration:

typescript
// src/application.ts
export class Application extends BaseApplication {
  preConfigure(): ValueOrPromise<void> {
    // Override options BEFORE registering component
    this.bind<IHealthCheckOptions>({ key: HealthCheckBindingKeys.HEALTH_CHECK_OPTIONS })
      .toValue({ restOptions: { path: '/api/health' } });

    this.component(HealthCheckComponent);
  }
}

Next Steps:

See Also ​