Skip to content

Fastify — full setup

Complete Fastify integration: plugin, outbound fetch, OpenAI, graceful shutdown.

Install

bash
npm install @amlexiahq/node fastify openai

Environment

env
AMLEXIA_SDK_KEY=am_...
AMLEXIA_INGEST_URL=https://ingest.amlexia.com
AMLEXIA_ENVIRONMENT=production
OPENAI_API_KEY=sk-...

Application

typescript
import Fastify from 'fastify';
import OpenAI from 'openai';
import {
  AmlexiaClient,
  wrapFetch,
  trackOpenAiCompletion,
} from '@amlexiahq/node';
import { amlexiaPlugin } from '@amlexiahq/node/fastify';

const client = new AmlexiaClient({
  sdkKey: process.env.AMLEXIA_SDK_KEY!,
  ingestUrl: process.env.AMLEXIA_INGEST_URL,
  environment: process.env.AMLEXIA_ENVIRONMENT,
  releaseVersion: process.env.AMLEXIA_RELEASE,
});

globalThis.fetch = wrapFetch(client, fetch);
const openai = new OpenAI();

const app = Fastify({ logger: true });

await app.register(amlexiaPlugin(client, { serviceName: 'api' }));

app.get('/health', async () => ({ ok: true }));

app.get('/api/users/:id', async (request) => {
  return { id: request.params.id };
});

app.post('/webhooks/stripe', async () => {
  return { received: true };
});

app.post('/api/chat', async (request) => {
  const body = request.body as { messages: OpenAI.ChatCompletionMessageParam[] };
  const start = Date.now();
  try {
    const completion = await openai.chat.completions.create({
      model: 'gpt-4o-mini',
      messages: body.messages,
    });
    trackOpenAiCompletion(client, {
      model: completion.model,
      statusCode: 200,
      latencyMs: Date.now() - start,
      usage: completion.usage,
    });
    return completion;
  } catch (e) {
    await client.track({
      endpoint: 'POST /api/chat',
      method: 'POST',
      statusCode: 500,
      latencyMs: Date.now() - start,
      provider: 'openai',
      errorMessage: e instanceof Error ? e.message : 'error',
    });
    throw e;
  }
});

const start = async () => {
  try {
    await app.listen({ port: Number(process.env.PORT) || 3000, host: '0.0.0.0' });
  } catch (err) {
    app.log.error(err);
    process.exit(1);
  }
};

const shutdown = async () => {
  await client.shutdown();
  await app.close();
  process.exit(0);
};

process.on('SIGTERM', shutdown);
process.on('SIGINT', shutdown);

start();

Plugin behavior

FeatureDetail
HooksonRequest + onResponse
PathsNormalized via Fastify route (/users/:id)
Tracingtraceparent response header
Headersx-session-id, x-user-id on trace context

Plugin options

OptionDefaultDescription
serviceName'api'service_name on events

Verify

bash
npx amlexia health
curl http://localhost:3000/health