Spraxium logoSpraxium

Configuração e Setup com Módulo Único

Configure @spraxium/http com um modelo global único de controle e comportamento de inicialização previsível. Mantenha os metadados HTTP ligados ao AppModule e registre o plugin por uma única entrada de configuração.

Controle da configuração em primeiro lugar

A decisão arquitetural mais importante é onde os metadados vivem. O HttpServer lê os metadados de HttpClientModule a partir da classe referenciada em defineHttp({ module }), então essa classe se torna a dona única de toda declaração de controller, service, guard e middleware da superfície HTTP. Usar AppModule como essa classe deixa o controle explícito e evita desvio silencioso de configuração quando a equipe refatora módulos.

Não é preciso um módulo wrapper local para HTTP

Evite criar um AppHttpModule separado apenas para hospedar os metadados de HttpClientModule. Mantenha HttpClientModule no AppModule, importe HttpModule no AppModule e referencie AppModule em defineHttp. Um segundo módulo com seu próprio HttpClientModule é ignorado silenciosamente pelo servidor, porque só a referência raiz é resolvida.

Esse modelo elimina ambiguidade de controle. Ciclo de vida do servidor, guards, middleware e registro de rotas apontam todos para uma única classe raiz e uma única entrada de plugin. Quando você adiciona um novo controller ou altera a pilha de guards, a mudança fica visível em um só lugar e passa a valer em toda a superfície da API sem mexer nos arquivos de configuração.

HttpConfig contract

HttpConfig é a interface que defineHttp() aceita e que ConfigStore entrega ao HttpServer no boot. Cada campo se mapeia para um comportamento específico de runtime, então entender esse contrato evita surpresas na implantação.

Subestrutura de SecurityConfig

O campo security aceita um objeto SecurityConfig com quatro subcampos opcionais. Cada subcampo controla uma camada da pilha de hardening e pode ser definido como false para desativá-la por completo. Quando um subcampo é omitido, o pacote aplica SECURITY_DEFAULTS automaticamente.

Separação de integração recomendada

Mantenha a chamada de defineHttp em um arquivo de configuração dedicado para que decisões de rede e segurança fiquem visíveis sem precisar percorrer decorators de módulo. O arquivo de configuração importa AppModule, e spraxium.config.ts importa esse arquivo. Esse padrão de três arquivos dá um lugar estável para cada responsabilidade: o arquivo de configuração controla a infraestrutura, o módulo controla os metadados e a configuração raiz controla o registro do plugin.

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,
});

Estrutura dos metadados de HttpClientModule

@HttpClientModule é um decorator de classe que armazena metadados consumidos por HttpServer durante o registro de rotas. Cada campo controla uma fase diferente do pipeline de inicialização.

A separação entre middleware e middlewareProviders deixa claro o limite entre política global de pipeline e declarações em nível de rota. Middleware global roda em toda requisição sem condição. Middleware de rota roda apenas em endpoints decorados com @HttpUseMiddleware e é resolvido sob demanda a partir do mapa de providers, então classes de middleware não referenciadas nunca são executadas.

Sequência de setup

Extraia a configuração do plugin para um arquivo dedicado

Mantenha a chamada de defineHttp em config/http.config.ts para que bind de rede, política de segurança e modo sharded fiquem visíveis em um só lugar. Isso também mantém spraxium.config.ts focado no registro do plugin, e não em detalhes de implementação. Variáveis de ambiente para host, porta e API key devem ser lidas aqui.

Aponte o módulo para sua composição raiz real

Defina module: AppModule em defineHttp para que HttpServer leia os metadados da mesma classe que controla o grafo de módulos. Criar um HttpAppModule separado leva a desvio, porque mudanças no AppModule não se propagam automaticamente para a fonte de metadados HTTP.

Importe HttpModule uma vez no AppModule

HttpModule é global e deve aparecer uma vez nas importações do módulo raiz. Isso garante um único responsável pelo ciclo de vida da inicialização e do desligamento gracioso do servidor. Importá-lo em vários módulos não causa erro, mas também não traz benefício.

Registre guards e middleware em HttpClientModule

Declare classes de guard customizadas no array @HttpClientModule() para proteção global. O framework resolve cada classe de guard por DI na inicialização. Instâncias de middleware vão em middleware e rodam depois da pilha de segurança. Middleware em nível de rota vai em middlewareProviders e é ativado por endpoint com @HttpUseMiddleware.

Registre uma única entrada de plugin HTTP em defineConfig

Mantenha uma única entrada de plugin HTTP dentro de defineConfig({plugins}). Entradas múltiplas levam a controle ambíguo e registro instável de rotas, porque ConfigStore devolve apenas uma configuração para a chave defineHttp.

Comportamento de inicialização por modo

ModoQuando iniciaExigência de client

Implementação de bridge

Direto, com sharding: false

Durante o hook de ciclo de vida onBoot, depois que o Client do Discord estiver pronto.

Obrigatório. Se faltar, o servidor registra erro e pula a inicialização.

DirectBotBridge: acessa o cache de guilds e a API do Discord diretamente pela instância do client.

Sharded, com sharding: true

Via ParentHookRegistry quando o processo pai cria o ShardingManager.

Não é obrigatório. O ShardingManager substitui o client nas interações com o bot.

ShardedBotBridge: usa manager.broadcastEval() para executar operações no shard que controla cada guild.

No modo direto, o servidor tem acesso imediato ao Client do Discord e pode injetá-lo no mapa de DI ao lado de BotBridge. Controllers que precisarem do client diretamente, em recursos não cobertos pelo bridge, podem declará-lo como parâmetro de construtor. No modo sharded, o client não está disponível no processo HTTP, então os controllers precisam usar BotBridge de forma exclusiva nas interações com o Discord.