Spraxium logoSpraxium

Configuración del Bot HTTP y Setup de Módulo Único

Configura @spraxium/http con un modelo global único de ownership y comportamiento de inicio predecible. Mantén metadatos HTTP en AppModule y registra el plugin mediante una única entrada de configuración.

Ownership de configuración primero

La decisión de arquitectura más importante es dónde viven los metadatos. HttpServer lee metadatos HttpClientModule desde la clase referenciada en defineHttp({ module }), por lo que esa clase se convierte en el único owner de cada declaración de controlador, servicio, guard y middleware en la superficie HTTP. Usar AppModule como esa clase mantiene explícito el ownership y evita drift silencioso de configuración cuando los equipos refactorizan módulos.

No necesitas un módulo wrapper HTTP local

Evita crear un AppHttpModule separado solo para alojar metadatos HttpClientModule. Mantén HttpClientModule en AppModule, importa HttpModule en AppModule y referencia AppModule en defineHttp. Un segundo módulo con su propio HttpClientModule será ignorado silenciosamente por el servidor porque solo se resuelve la referencia raíz.

Este modelo elimina ambigüedad de ownership. Ciclo de vida del servidor, guards, middleware y registro de rutas apuntan a una sola clase raíz y una sola entrada de plugin. Cuando agregas un nuevo controlador o cambias el stack de guards, el cambio se ve en un solo lugar y toma efecto en toda la superficie API sin tocar archivos de configuración.

Contrato HttpConfig

HttpConfig es la interfaz que acepta defineHttp() y que ConfigStore entrega a HttpServer en tiempo de boot. Cada campo se mapea a un comportamiento runtime específico, así que entender el contrato evita sorpresas en despliegue.

Subestructura de SecurityConfig

El campo security acepta un objeto SecurityConfig con cuatro subcampos opcionales. Cada subcampo controla una capa del stack de hardening y puede establecerse en false para desactivarla por completo. Cuando un subcampo se omite, el paquete aplica SECURITY_DEFAULTS automáticamente.

División de integración recomendada

Mantén la llamada a defineHttp en un archivo de config dedicado para que decisiones de red y seguridad sean visibles sin desplazarte por decoradores de módulo. El archivo de config importa AppModule, y spraxium.config.ts importa ese archivo de config. Este patrón de tres archivos da un hogar estable a cada responsabilidad: el archivo de config controla infraestructura, el módulo controla metadatos y la config raíz controla registro de plugins.

import { defineHttp } from '@spraxium/http';
import { AppModule } from '../src/app.module';

export const httpPlugin = defineHttp({
  enabled: true,
  host: process.env.HTTP_HOST ?? '0.0.0.0',
  port: Number(process.env.HTTP_PORT ?? 3000),
  apiKey: process.env.HTTP_API_KEY ?? '',
  sharding: false,
  security: {
    hidePoweredBy: true,
    headers: {
      frameOptions: 'DENY',
      contentSecurityPolicy: "default-src 'none'",
      referrerPolicy: 'no-referrer',
    },
    cors: {
      origins: ['https://admin.example.com'],
      methods: ['GET', 'POST', 'PATCH'],
      allowedHeaders: ['Content-Type', 'Authorization', 'X-Api-Key'],
      credentials: true,
    },
    bodyLimit: { maxSize: 256_000 },
  },
  module: AppModule,
});

Forma de metadatos de HttpClientModule

@HttpClientModule es un decorador de clase que almacena metadatos consumidos por HttpServer durante el registro de rutas. Cada campo controla una fase distinta del pipeline de startup.

La separación entre middleware y middlewareProviders da ownership claro entre política global de pipeline y declaraciones de nivel ruta. El middleware global corre en todas las requests sin condición. El middleware de ruta corre solo en endpoints decorados con @HttpUseMiddleware y se resuelve de forma perezosa desde el mapa de providers, por lo que clases middleware no referenciadas nunca se ejecutan.

Secuencia de setup

Extrae configuración de plugin a un archivo dedicado

Mantén la llamada defineHttp en config/http.config.ts para que el enlace de red, la política de seguridad y el modo sharding sean visibles en un único lugar. Esto también mantiene spraxium.config.ts enfocado en registro de plugins en lugar de detalles de implementación. Variables de entorno para host, puerto y API key deberían leerse aquí.

Apunta module a tu composición real raíz

Establece module: AppModule en defineHttp para que HttpServer lea metadatos desde la misma clase que controla el grafo de módulos. Crear un HttpAppModule separado produce drift porque cambios en AppModule no se propagan automáticamente a la fuente de metadatos HTTP.

Importa HttpModule una sola vez en AppModule

HttpModule es global y debería aparecer una vez en imports del módulo raíz. Eso asegura un único owner de ciclo de vida para inicio del servidor y apagado ordenado. Importarlo en múltiples módulos no causa errores, pero no aporta beneficios.

Registra guards y middleware en HttpClientModule

Declara clases guard personalizadas en el arreglo @HttpClientModule() para protección global. El framework resuelve cada clase guard vía DI en startup. Las instancias middleware van en middleware y corren después del stack de seguridad. El middleware por ruta va en middlewareProviders y se activa por endpoint con @HttpUseMiddleware.

Registra una sola entrada HTTP plugin en defineConfig

Mantén una sola entrada de plugin HTTP dentro de defineConfig({plugins}). Múltiples entradas llevan a ownership ambiguo y registro de rutas inestable porque ConfigStore devuelve una sola config para la clave defineHttp.

Comportamiento de inicio por modo

ModoCuándo iniciaRequisito de client

Implementación de bridge

Directo, con sharding: false

Durante el hook de ciclo de vida onBoot, después de que el Client de Discord está listo.

Requerido. Si falta, el servidor registra error en logs y omite el startup.

DirectBotBridge: accede a caché de guilds y API de Discord a través de la instancia client directamente.

Sharded, con sharding: true

Vía ParentHookRegistry cuando el proceso padre crea el ShardingManager.

No requerido. El ShardingManager reemplaza al client para interacciones con el bot.

ShardedBotBridge: usa manager.broadcastEval() para ejecutar operaciones en el shard dueño de cada guild.

En modo directo, el servidor tiene acceso inmediato al Client de Discord y puede inyectarlo en el mapa DI junto con BotBridge. Los controladores que necesiten el client de forma directa (para funciones no cubiertas por bridge) pueden declararlo como parámetro de constructor. En modo sharded, el client no está disponible en el proceso HTTP, así que los controladores deben usar BotBridge exclusivamente para interactuar con Discord.