Express Basic
A minimal Express app with NjiraAI enforcement and tracing.
This example shows a simple Express server that enforces policies before processing chat messages.
Full code
import express from "express";
import { NjiraAI } from "@njiraai/sdk";
const app = express();
app.use(express.json());
const njira = new NjiraAI({
apiKey: process.env.NJIRA_API_KEY!,
projectId: process.env.NJIRA_PROJECT_ID!,
mode: "active",
failStrategy: "fail_closed",
});
// Add middleware for context propagation and trace flushing
app.use(njira.middleware.express());
app.post("/chat", async (req, res) => {
const { message } = req.body;
// Pre-enforcement: check input before LLM call
const pre = await njira.enforcePre({
input: message,
metadata: { endpoint: "/chat", source: "user" },
});
if (pre.verdict === "block") {
return res.status(403).json({
error: "Message blocked by policy",
reasons: pre.reasons,
traceId: pre.traceId,
});
}
// Use modified input if policy rewrote it
const effectiveInput = pre.verdict === "modify" ? pre.modifiedInput : message;
// Start a span for the LLM call
const spanId = njira.trace.startSpan({
name: "llm-call",
type: "llm",
input: { prompt: effectiveInput },
});
try {
// Simulate LLM response
const llmResponse = `I received: "${effectiveInput}"`;
njira.trace.endSpan(spanId, { output: llmResponse });
// Post-enforcement: check output before returning
const post = await njira.enforcePost({
output: llmResponse,
metadata: { endpoint: "/chat" },
});
if (post.verdict === "block") {
return res.status(403).json({
error: "Response blocked by policy",
reasons: post.reasons,
traceId: post.traceId,
});
}
const finalResponse =
post.verdict === "modify" ? post.modifiedOutput : llmResponse;
res.json({ response: finalResponse, traceId: pre.traceId });
} catch (error) {
njira.trace.error(spanId, error as Error);
res.status(500).json({ error: "Internal error" });
}
});
app.listen(3000, () => {
console.log("Server running on http://localhost:3000");
});
Run it
cd sdks/typescript/examples/express-basic
pnpm install
NJIRA_API_KEY=your-key NJIRA_PROJECT_ID=your-project pnpm dev
Test it
curl -X POST http://localhost:3000/chat \
-H "Content-Type: application/json" \
-d '{"message": "Hello, world!"}'
What's happening
- Middleware sets up request context and ensures traces flush on response
enforcePrechecks the input against configured policies- Span tracks the LLM call duration and I/O
enforcePostvalidates the output before returning to the user