CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-loopback--core

Define and implement core constructs such as Application and Component for LoopBack 4 framework

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

components.mddocs/

Component System

The Component system in LoopBack Core provides a modular architecture for packaging and contributing functionality to applications. Components can declare controllers, providers, servers, lifecycle observers, services, bindings, and even sub-components, making applications highly composable and extensible.

Capabilities

Component Interface

The core interface that defines what resources a component can contribute to an application.

/**
 * A component declares a set of artifacts so that they can be contributed to
 * an application as a group
 */
interface Component {
  /** An array of controller classes */
  controllers?: ControllerClass[];
  
  /** A map of providers to be bound to the application context */
  providers?: ProviderMap;
  
  /** A map of classes to be bound to the application context */
  classes?: ClassMap;
  
  /** A map of name/class pairs for servers */
  servers?: { [name: string]: Constructor<Server> };
  
  /** An array of lifecycle observer classes */
  lifeCycleObservers?: Constructor<LifeCycleObserver>[];
  
  /** An array of service or provider classes */
  services?: ServiceOrProviderClass[];
  
  /** An array of bindings to be added to the application context */
  bindings?: Binding[];
  
  /** An array of component classes */
  components?: Constructor<Component>[];
  
  /** Other properties */
  [prop: string]: any;
}

Usage Examples:

import { Component, ControllerClass, LifeCycleObserver } from "@loopback/core";

// Basic component with controllers
class ProductComponent implements Component {
  controllers = [ProductController, CategoryController];
}

// Comprehensive component
class EcommerceComponent implements Component {
  controllers = [
    ProductController,
    CategoryController,
    OrderController
  ];
  
  providers = {
    'services.payment': PaymentServiceProvider,
    'services.shipping': ShippingServiceProvider
  };
  
  classes = {
    'repositories.product': ProductRepository,
    'repositories.order': OrderRepository
  };
  
  servers = {
    'webhook': WebhookServer
  };
  
  lifeCycleObservers = [
    DatabaseMigrationObserver,
    CacheWarmupObserver
  ];
  
  services = [
    EmailService,
    LoggingService
  ];
  
  bindings = [
    Binding.bind('config.ecommerce').to({
      currency: 'USD',
      taxRate: 0.08
    })
  ];
  
  components = [
    AuthenticationComponent,
    ValidationComponent
  ];
}

Component Mounting

Function that mounts a component instance to an application, registering all declared resources.

/**
 * Mount a component to an Application.
 */
function mountComponent(app: Application, component: Component): void;

Usage Examples:

import { Application, mountComponent, Component } from "@loopback/core";

class MyComponent implements Component {
  controllers = [UserController];
  providers = {
    'services.logger': LoggerProvider
  };
}

const app = new Application();
const componentInstance = new MyComponent();

// Mount component manually
mountComponent(app, componentInstance);

// Typically done automatically when using app.component()
app.component(MyComponent); // This calls mountComponent internally

Provider Map

Map interface for organizing provider classes by binding key.

/**
 * A map of provider classes to be bound to a context
 */
interface ProviderMap {
  [key: string]: Constructor<Provider<BoundValue>>;
}

Usage Examples:

import { Component, Provider, ProviderMap } from "@loopback/core";

// Email service provider
class EmailServiceProvider implements Provider<EmailService> {
  value(): EmailService {
    return new EmailService({
      apiKey: process.env.EMAIL_API_KEY,
      baseUrl: 'https://api.emailservice.com'
    });
  }
}

// Configuration provider
class AppConfigProvider implements Provider<AppConfig> {
  value(): AppConfig {
    return {
      database: {
        host: process.env.DB_HOST || 'localhost',
        port: parseInt(process.env.DB_PORT || '5432')
      },
      redis: {
        url: process.env.REDIS_URL || 'redis://localhost:6379'
      }
    };
  }
}

// Component using provider map
class CoreServicesComponent implements Component {
  providers: ProviderMap = {
    'services.email': EmailServiceProvider,
    'services.config': AppConfigProvider,
    'services.logger': LoggerServiceProvider,
    'services.metrics': MetricsServiceProvider
  };
}

Class Map

Map interface for organizing regular classes by binding key.

/**
 * A map of classes to be bound to a context
 */
interface ClassMap {
  [key: string]: Constructor<BoundValue>;
}

Usage Examples:

import { Component, ClassMap } from "@loopback/core";

// Repository classes
class UserRepository {
  constructor(
    @inject('datasources.db') private datasource: DataSource
  ) {}
  
  async findById(id: string): Promise<User | null> {
    // Repository implementation
    return null;
  }
}

class ProductRepository {
  constructor(
    @inject('datasources.db') private datasource: DataSource
  ) {}
  
  async findByCategory(category: string): Promise<Product[]> {
    // Repository implementation
    return [];
  }
}

// Component using class map
class RepositoryComponent implements Component {
  classes: ClassMap = {
    'repositories.user': UserRepository,
    'repositories.product': ProductRepository,
    'repositories.order': OrderRepository,
    'services.cache': CacheService
  };
}

Component Composition

Components can include other components, enabling hierarchical composition and modularity.

Usage Examples:

import { Component } from "@loopback/core";

// Base authentication component
class AuthenticationComponent implements Component {
  providers = {
    'auth.strategy.jwt': JwtStrategyProvider,
    'auth.strategy.oauth': OAuthStrategyProvider
  };
  
  services = [
    TokenService,
    UserService
  ];
}

// Authorization component that builds on authentication
class AuthorizationComponent implements Component {
  components = [
    AuthenticationComponent // Include authentication
  ];
  
  providers = {
    'auth.rbac': RoleBasedAccessControlProvider,
    'auth.permissions': PermissionServiceProvider
  };
}

// Main application component that includes everything
class AppComponent implements Component {
  components = [
    AuthorizationComponent, // This transitively includes AuthenticationComponent
    LoggingComponent,
    DatabaseComponent
  ];
  
  controllers = [
    AppController,
    HealthController
  ];
}

Server Component Integration

Components can contribute server implementations for different protocols.

Usage Examples:

import { Component, Server, LifeCycleObserver } from "@loopback/core";

class RestServer implements Server, LifeCycleObserver {
  listening = false;
  
  async start(): Promise<void> {
    // Start REST server
    this.listening = true;
  }
  
  async stop(): Promise<void> {
    // Stop REST server  
    this.listening = false;
  }
}

class GraphQLServer implements Server, LifeCycleObserver {
  listening = false;
  
  async start(): Promise<void> {
    // Start GraphQL server
    this.listening = true;
  }
  
  async stop(): Promise<void> {
    // Stop GraphQL server
    this.listening = false;
  }
}

// Multi-protocol component
class ApiComponent implements Component {
  servers = {
    'rest': RestServer,
    'graphql': GraphQLServer
  };
  
  controllers = [
    RestApiController,
    GraphQLController
  ];
  
  lifeCycleObservers = [
    ServerStartupObserver,
    ServerHealthCheckObserver
  ];
}

Binding Integration

Components can contribute pre-configured bindings for complex setup scenarios.

Usage Examples:

import { Component, Binding, BindingScope } from "@loopback/core";

class DatabaseComponent implements Component {
  bindings = [
    // Database connection binding
    Binding.bind('datasources.primary')
      .toProvider(DatabaseConnectionProvider)
      .inScope(BindingScope.SINGLETON),
    
    // Connection pool configuration
    Binding.bind('config.database.pool')
      .to({
        min: 2,
        max: 10,
        acquireTimeoutMillis: 60000,
        createTimeoutMillis: 30000
      }),
    
    // Migration configuration
    Binding.bind('config.database.migrations')
      .to({
        directory: './migrations',
        autoRun: process.env.NODE_ENV !== 'production'
      })
  ];
  
  lifeCycleObservers = [
    DatabaseMigrationObserver
  ];
}

Service Integration

Components can contribute services and providers for application-wide functionality.

Usage Examples:

import { Component, ServiceOrProviderClass } from "@loopback/core";

// Service classes
class EmailService {
  async sendEmail(to: string, subject: string, body: string): Promise<void> {
    // Implementation
  }
}

class SmsService {
  async sendSms(to: string, message: string): Promise<void> {
    // Implementation
  }
}

// Provider for external API
class WeatherServiceProvider implements Provider<WeatherService> {
  value(): WeatherService {
    return new WeatherService(process.env.WEATHER_API_KEY);
  }
}

// Communication services component
class CommunicationComponent implements Component {
  services: ServiceOrProviderClass[] = [
    EmailService,
    SmsService,
    WeatherServiceProvider,
    NotificationService
  ];
  
  providers = {
    'services.communication.config': CommunicationConfigProvider
  };
}

Types

interface ProviderMap {
  [key: string]: Constructor<Provider<BoundValue>>;
}

interface ClassMap {
  [key: string]: Constructor<BoundValue>;
}

type ControllerClass<T = any> = Constructor<T>;

type ServiceOrProviderClass<T = any> = 
  | Constructor<T | Provider<T>>
  | DynamicValueProviderClass<T>;

docs

application.md

components.md

context-api.md

extensions.md

index.md

lifecycle.md

services.md

tile.json