Skip to content

DefaultApplication

Overview

DefaultApplication is the foundational application class that every backend service in the BANA system extends. It inherits from the IGNIS framework's BaseApplication and provides a standardized setup for:

  • CORS and body-limit middleware
  • JWT and Basic authentication strategies
  • Health check endpoint
  • Swagger/OpenAPI documentation with Scalar UI
  • Static file serving
  • IdentityNetworkService registration for cross-service authentication

Source: packages/core/src/default-application.ts

See the IGNIS Application reference for details on the parent BaseApplication class.

Class Definition

typescript
import { BaseApplication, IApplicationInfo } from '@venizia/ignis';

export class DefaultApplication extends BaseApplication {
  protected applicationRoles: string[] = [];

  // Configuration helpers
  getApplicationRoles(): string[];
  override getAppInfo(): IApplicationInfo;

  // Lifecycle hooks
  preConfigure(): void;
  async postConfigure(): Promise<void>;

  // Middleware
  override async setupMiddlewares(): Promise<void>;

  // Registration methods (override in child classes)
  staticConfigure(): void;
  configureDatasources(): void;
  configureRepositories(): void;
  configureServices(): void;
  configureComponents(): void;
  configureSecurity(): void;
  configureControllers(): void;
}

Inheritance Diagram

Lifecycle and Boot Sequence

preConfigure() Call Order

The preConfigure() method is called by the IGNIS framework before the application starts. It invokes the registration methods in a fixed order:

typescript
preConfigure() {
  this.applicationRoles = this.getApplicationRoles();

  this.configureDatasources();   // 1. Data sources
  this.configureRepositories();  // 2. Repositories
  this.configureServices();      // 3. Services
  this.configureComponents();    // 4. Components (HealthCheck, Swagger)
  this.configureSecurity();      // 5. Authentication strategies
  this.configureControllers();   // 6. Controllers
}

Full Boot Sequence

Middleware Configuration

CORS

The CORS middleware is configured with permissive defaults suitable for development and API gateway deployments.

typescript
cors: {
  enable: true,
  path: '*',
  origin: '*',
  allowMethods: ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'],
  allowHeaders: [/* see table below */],
  exposeHeaders: [/* see table below */],
  maxAge: 86_400,  // 24 hours
  credentials: true,
}

Allowed Request Headers:

HeaderIGNIS Constant
AuthorizationHTTP.Headers.AUTHORIZATION
Content-TypeHTTP.Headers.CONTENT_TYPE
X-Request-ChannelHTTP.Headers.REQUEST_CHANNEL
X-Count-DataHTTP.Headers.REQUEST_COUNT_DATA
X-Device-InfoHTTP.Headers.REQUEST_DEVICE_INFO
X-Tracing-IdHTTP.Headers.REQUEST_TRACING_ID
timezoneCustom
timezone-offsetCustom
x-auth-providerCustom
x-forward-forCustom
x-localeCustom
x-real-ipCustom

Exposed Response Headers:

HeaderIGNIS Constant
Content-LengthHTTP.Headers.CONTENT_LENGTH
Content-RangeHTTP.Headers.CONTENT_RANGE
Content-TypeHTTP.Headers.CONTENT_TYPE
X-Count-DataHTTP.Headers.RESPONSE_COUNT_DATA
X-Response-FormatHTTP.Headers.RESPONSE_FORMAT
x-custom-headerCustom

Body Limit

typescript
bodyLimit: {
  enable: true,
  path: '*',
  maxSize: 100 * 1024 * 1024,  // 100 MB
  onError: c => c.json({}, 413),  // HTTP 413 Content Too Large
}

Component Setup

Health Check

Registered at the /health endpoint. Returns application status information.

typescript
this.bind<IHealthCheckOptions>({
  key: HealthCheckBindingKeys.HEALTH_CHECK_OPTIONS,
}).toValue({
  restOptions: { path: '/health' },
});
this.component(HealthCheckComponent);

See the IGNIS Health Check reference for response format and customization.

Swagger / OpenAPI

Provides three endpoints for API documentation:

PathDescription
/docDocumentation base path
/openapi.jsonOpenAPI 3.0 specification (JSON)
/explorerScalar API reference UI
typescript
this.bind<ISwaggerOptions>({ key: SwaggerBindingKeys.SWAGGER_OPTIONS }).toValue({
  restOptions: {
    base: { path: '/doc' },
    doc: { path: '/openapi.json' },
    ui: { path: '/explorer', type: 'scalar' },
  },
  explorer: {
    openapi: '3.0.0',
    info: {
      title: 'API Documentation',
      version: this.getAppInfo().version,
      description: 'API documentation for your service',
    },
    servers: [
      {
        url: applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_APPLICATION_EXPLORER_URL),
        description: 'Application Server URL',
      },
    ],
  },
});
this.component(SwaggerComponent);

See the IGNIS Swagger reference for full options.

Security Setup

JWT Authentication

Configured using three environment variables:

VariableDescription
APP_ENV_APPLICATION_SECRETApplication-level secret
APP_ENV_JWT_SECRETJWT signing secret
APP_ENV_JWT_EXPIRES_INToken expiration in seconds
typescript
this.bind<IJWTTokenServiceOptions>({
  key: AuthenticateBindingKeys.JWT_OPTIONS,
}).toValue({
  applicationSecret: applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_APPLICATION_SECRET),
  jwtSecret: applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_JWT_SECRET),
  getTokenExpiresFn: () => {
    const jwtExpiresIn = applicationEnvironment.get<string>(EnvironmentKeys.APP_ENV_JWT_EXPIRES_IN);
    return parseInt(jwtExpiresIn);
  },
});

Basic Authentication

Basic auth is delegated to the Identity Service via IdentityNetworkService.signIn(). When a controller uses @authenticate(['basic']), the credentials are forwarded to the identity service for validation.

typescript
this.bind<IBasicTokenServiceOptions>({
  key: AuthenticateBindingKeys.BASIC_OPTIONS,
}).toValue({
  verifyCredentials: async (opts) => {
    const identityNetworkService = this.get<IdentityNetworkService>({
      key: 'services.IdentityNetworkService',
    });

    return identityNetworkService.signIn({
      identifier: { scheme: 'username', value: opts.credentials.username },
      credential: { scheme: 'basic', value: opts.credentials.password },
    });
  },
});

Strategy Registration

Both strategies are registered with the IGNIS AuthenticationStrategyRegistry:

typescript
this.component(AuthenticateComponent);
AuthenticationStrategyRegistry.getInstance().register({
  container: this,
  strategies: [
    { name: Authentication.STRATEGY_JWT, strategy: JWTAuthenticationStrategy },
    { name: Authentication.STRATEGY_BASIC, strategy: BasicAuthenticationStrategy },
  ],
});

See the IGNIS Authentication reference for strategy details.

Authentication Flow

Static File Serving

The staticConfigure() method serves files from the public/ directory relative to the @nx/core package:

typescript
staticConfigure(): void {
  this.static({ folderPath: path.join(__dirname, '../public') });
}

How to Extend in Child Packages

Every package creates its own Application class that extends DefaultApplication and overrides the registration methods:

typescript
// packages/sale/src/application.ts
import { DefaultApplication } from '@nx/core';

export class Application extends DefaultApplication {
  override preConfigure(): void {
    // Call the parent — registers IdentityNetworkService,
    // HealthCheck, Swagger, JWT, Basic auth
    super.preConfigure();

    // Additional package-specific setup happens in overridden methods
  }

  override configureDatasources(): void {
    super.configureDatasources();
    // Register package-specific datasources if needed
  }

  override configureRepositories(): void {
    super.configureRepositories();
    this.repository(SaleOrderRepository);
    this.repository(SaleOrderItemRepository);
  }

  override configureServices(): void {
    super.configureServices();
    this.service(SaleOrderService);
    this.service(CheckoutService);
  }

  override configureComponents(): void {
    super.configureComponents();
    this.component(ApplicationPaymentComponent);
  }

  override configureControllers(): void {
    super.configureControllers();
    this.controller(SaleOrderController);
  }

  override async postConfigure(): Promise<void> {
    await super.postConfigure();
    // Run after all components are bound
  }
}

Always call super

When overriding any registration method, always call super.<method>() first to preserve the default registrations (IdentityNetworkService, HealthCheck, Swagger, JWT/Basic auth).

Environment Variables

VariableRequiredDescription
APP_ENV_APPLICATION_SECRETYesApplication-level secret for JWT
APP_ENV_JWT_SECRETYesJWT signing secret
APP_ENV_JWT_EXPIRES_INYesToken expiration in seconds
APP_ENV_APPLICATION_ROLESNoComma-separated role identifiers
APP_ENV_IDENTITY_SERVICE_BASE_URLYesIdentity service URL for Basic auth delegation
APP_ENV_APPLICATION_EXPLORER_URLNoServer URL shown in Swagger explorer

Proprietary and Confidential. Unauthorized copying, distribution, or use of this software is strictly prohibited.