Skip to content

Examples

All examples are available in the SDK repository.

Protect routes with the built-in middleware:

// Usage: npx tsx examples/express-basic.ts
import express from 'express';
import { Rakomi } from '@rakomi/node';
const app = express();
const ca = new RakomiClient({ apiKey: 'akm_live_your_api_key' });
// Protect all /api routes — auto-detects dev/prod from hostname
app.use('/api', ca.middleware());
// Access authenticated user data via req.auth
app.get('/api/profile', (req, res) => {
const { userId, email, tenantId } = (req as any).auth;
res.json({ userId, email, tenantId });
});
// Public route — no middleware
app.get('/health', (_req, res) => {
res.json({ status: 'ok' });
});
app.listen(3000, () => {
console.log('Server running on http://localhost:3000');
});

Verify webhook signatures with raw body handling:

// Usage: npx tsx examples/express-webhook.ts
import express from 'express';
import { Rakomi } from '@rakomi/node';
const app = express();
const ca = new RakomiClient({
apiKey: 'akm_live_your_api_key',
webhookSecret: 'whsec_your_webhook_secret',
});
// Webhook route must use raw body (not parsed JSON)
app.post('/webhooks/rakomi', express.raw({ type: '*/*' }), async (req, res) => {
const result = await ca.verifyWebhook(req.body as Buffer, req.headers);
if (!result.ok) {
console.error('Webhook verification failed:', result.error.code);
res.status(400).json({ error: result.error.code });
return;
}
const { payload, deliveryId } = result.data;
console.log(`Received ${payload.type} (delivery: ${deliveryId})`);
switch (payload.type) {
case 'user.created':
console.log('New user:', payload.data);
break;
case 'user.deleted':
console.log('User deleted:', payload.userId);
break;
}
res.status(200).json({ received: true });
});
app.listen(3000, () => {
console.log('Webhook server running on http://localhost:3000');
});

Wrap the Rakomi middleware as a Fastify preHandler:

// Usage: npx tsx examples/fastify-basic.ts
import Fastify from 'fastify';
import { Rakomi } from '@rakomi/node';
const fastify = Fastify({ logger: true });
const ca = new RakomiClient({ apiKey: 'akm_live_your_api_key' });
const authMiddleware = ca.middleware();
fastify.addHook('preHandler', (request, reply, done) => {
if (request.url === '/health') {
done();
return;
}
const req = { headers: request.headers, auth: undefined as any };
const res = {
status: (code: number) => {
reply.code(code);
return res;
},
json: (body: unknown) => void reply.send(body),
};
authMiddleware(req, res, () => {
(request as any).auth = req.auth;
done();
});
});
fastify.get('/api/profile', async (request) => {
const { userId, email, tenantId } = (request as any).auth;
return { userId, email, tenantId };
});
fastify.get('/health', async () => ({ status: 'ok' }));
fastify.listen({ port: 3000 }, () => {
console.log('Fastify server running on http://localhost:3000');
});

Use verifyToken() directly in Hono middleware:

// Usage: npx tsx examples/hono-basic.ts
import { Hono } from 'hono';
import { serve } from '@hono/node-server';
import { Rakomi } from '@rakomi/node';
const app = new Hono();
const ca = new RakomiClient({ apiKey: 'akm_live_your_api_key' });
app.use('/api/*', async (c, next) => {
const result = await ca.verifyToken(
c.req.header('authorization')?.slice(7) ?? '',
);
if (!result.ok) {
const { code, message, docs_url } = result.error;
return c.json({ error: { code, message, docs_url } }, 401);
}
c.set('auth' as never, result.data as never);
await next();
});
app.get('/api/profile', (c) => {
const auth = c.get('auth' as never) as { userId: string; email: string };
return c.json({ userId: auth.userId, email: auth.email });
});
app.get('/health', (c) => c.json({ status: 'ok' }));
serve({ fetch: app.fetch, port: 3000 }, () => {
console.log('Hono server running on http://localhost:3000');
});

Protect Next.js routes at the edge:

// Copy to your Next.js project root as middleware.ts
import { NextResponse, type NextRequest } from 'next/server';
import { Rakomi } from '@rakomi/node';
const ca = new RakomiClient({ apiKey: 'akm_live_your_api_key' });
export async function middleware(request: NextRequest) {
if (request.nextUrl.pathname.startsWith('/public')) {
return NextResponse.next();
}
const token = request.headers.get('authorization')?.slice(7);
if (!token) {
return NextResponse.json({ error: 'Missing token' }, { status: 401 });
}
const result = await ca.verifyToken(token);
if (!result.ok) {
const { code, message, docs_url } = result.error;
return NextResponse.json({ error: { code, message, docs_url } }, { status: 401 });
}
const response = NextResponse.next();
response.headers.set('x-user-id', result.data.userId);
response.headers.set('x-tenant-id', result.data.tenantId);
return response;
}
export const config = {
matcher: ['/api/:path*', '/dashboard/:path*'],
};