SDK Node.js
O pacote @flagbridge/sdk-node fornece avaliação de feature flags para Node.js e TypeScript server-side.
Instalação
npm install @flagbridge/sdk-nodepnpm add @flagbridge/sdk-nodeyarn add @flagbridge/sdk-nodeRequisitos: Node.js 18+ · TypeScript 5+ (opcional)
Início rápido
import { FlagBridgeClient } from '@flagbridge/sdk-node';
const client = new FlagBridgeClient({
apiKey: process.env.FLAGBRIDGE_API_KEY!,
// baseUrl padrão: https://api.flagbridge.io
});
// Flag booleana
const habilitado = await client.isEnabled('novo-checkout', {
userId: 'user-123',
plan: 'pro',
});
// Flag multi-variante
const variante = await client.getVariant('cor-botao-checkout', {
userId: 'user-123',
});
// variante.value → "verde" | "azul" | "vermelho"
// variante.enabled → trueConfiguração
const client = new FlagBridgeClient({
// Obrigatório
apiKey: 'fb_live_...',
// Opcional
baseUrl: 'https://api.flagbridge.io', // ou seu URL self-hosted
environment: 'production', // sobrescrever ambiente
timeout: 5000, // timeout da requisição em ms (padrão: 5000)
cache: {
ttl: 30_000, // TTL do cache em memória em ms (padrão: 30s)
maxSize: 1000, // máximo de entradas em cache
},
onError: (err) => { // handler de erro personalizado
console.error('[FlagBridge]', err);
},
});INFO
Por padrão, erros de avaliação retornam false (flag desabilitada) para que falhas de avaliação nunca quebrem sua aplicação.
API
isEnabled(flagKey, context?)
Avalia uma flag booleana. Retorna true se a flag estiver habilitada para o contexto fornecido.
const habilitado = await client.isEnabled('minha-flag', {
userId: 'user-123',
country: 'BR',
plan: 'pro',
});
// → true | falsegetVariant(flagKey, context?)
Avalia uma flag multi-variante e retorna o resultado da variante.
const resultado = await client.getVariant('cor-botao', {
userId: 'user-123',
});
resultado.value; // "verde" — o valor da variante
resultado.enabled; // true
resultado.reason; // "TARGETING_RULE_MATCH" | "PERCENTAGE_ROLLOUT" | ...evaluate(flagKey, context?)
Avaliação de baixo nível — retorna o objeto de resultado completo.
const resultado = await client.evaluate('minha-flag', { userId: 'user-123' });
resultado.flagKey; // "minha-flag"
resultado.enabled; // true
resultado.variant; // null (ou string para flags multi-variantes)
resultado.reason; // "TARGETING_RULE_MATCH"
resultado.ruleId; // "rule_abc123"evaluateBatch(flags, context?)
Avalia múltiplas flags em uma única requisição.
const resultados = await client.evaluateBatch(
['novo-checkout', 'modo-escuro', 'sidebar-v2'],
{ userId: 'user-123' }
);
resultados['novo-checkout'].enabled; // true
resultados['modo-escuro'].enabled; // falseclose()
Finaliza requisições pendentes e fecha o cliente. Chame ao desligar a aplicação.
await client.close();Cache
O SDK armazena em cache os resultados de avaliação na memória para evitar latência em cada requisição. O cache é indexado por (flagKey, hash do contexto).
const client = new FlagBridgeClient({
apiKey: '...',
cache: {
ttl: 60_000, // cachear por 60 segundos
maxSize: 500, // evicção LRU ao atingir este limite
},
});Para desabilitar o cache (útil em testes):
const client = new FlagBridgeClient({
apiKey: '...',
cache: false,
});Helpers de teste CE
O SDK inclui um TestingClient para uso na sua suíte de testes. Ele usa a API de Testing do FlagBridge para criar sessões isoladas com overrides por flag.
import { createTestingClient } from '@flagbridge/sdk-node/testing';
// Na configuração dos seus testes
const testClient = createTestingClient({
apiKey: process.env.FLAGBRIDGE_TEST_API_KEY!,
baseUrl: 'http://localhost:8080',
});
// Antes de cada teste
const session = await testClient.createSession();
// Sobrescrever flags específicas para esta sessão
await session.override('novo-checkout', true);
await session.override('cor-botao-checkout', 'verde');
// Execute seu teste com o token da sessão
// Passe o token no header das suas requisições HTTP:
// X-FlagBridge-Session: <session.token>
// Após cada teste
await session.destroy();Veja o guia de testes E2E para exemplos completos com Playwright e Vitest.
Integrações com frameworks
Express / Fastify
import { flagBridgeMiddleware } from '@flagbridge/sdk-node/middleware';
// Express
app.use(flagBridgeMiddleware({
client,
contextFromRequest: (req) => ({
userId: req.user?.id,
plan: req.user?.plan,
}),
}));
// Agora req.flags está disponível nos seus handlers
app.get('/checkout', async (req, res) => {
if (req.flags.isEnabled('novo-checkout')) {
return res.render('checkout-v2');
}
return res.render('checkout');
});Next.js (App Router)
// lib/flags.ts
import { FlagBridgeClient } from '@flagbridge/sdk-node';
export const flagbridge = new FlagBridgeClient({
apiKey: process.env.FLAGBRIDGE_API_KEY!,
});
// app/checkout/page.tsx
import { flagbridge } from '@/lib/flags';
import { cookies } from 'next/headers';
export default async function PaginaCheckout() {
const userId = (await cookies()).get('user_id')?.value;
const novoCheckout = await flagbridge.isEnabled('novo-checkout', {
userId,
});
if (novoCheckout) {
return <NovoCheckout />;
}
return <CheckoutAntigo />;
}TypeScript
Todos os métodos são totalmente tipados. Você pode declarar as chaves das suas flags para autocomplete e type safety:
import { FlagBridgeClient } from '@flagbridge/sdk-node';
// Declarar as chaves das suas flags
type FlagKey =
| 'novo-checkout'
| 'cor-botao-checkout'
| 'modo-escuro';
const client = new FlagBridgeClient<FlagKey>({ apiKey: '...' });
// Agora flagKey é tipada
client.isEnabled('novo-checkout', { userId: 'user-123' }); // ✓
client.isEnabled('flag-com-typo', { userId: 'user-123' }); // ✗ Erro TypeScriptTratamento de erros
Por padrão, falhas de avaliação retornam false silenciosamente. Use onError para personalizar:
const client = new FlagBridgeClient({
apiKey: '...',
onError: (error) => {
// Registrar no seu sistema de rastreamento de erros
Sentry.captureException(error);
},
});Para tratamento explícito de erros, use evaluate() com try/catch:
try {
const resultado = await client.evaluate('minha-flag', { userId: 'user-123' });
} catch (err) {
// Tratar erro explicitamente
}Changelog
Veja os releases do SDK Node.js no GitHub.
