Node.js Integration Guide
The @ztlayer/node SDK provides high-performance, low-level bindings for securing raw Node.js http and https servers, as well as modern, fast frameworks like Fastify.
If you are using Express, please refer to the dedicated Express Integration Guide.
1. Installation
Install the Node.js SDK:
npm install @ztlayer/node2. Configuration & Initialization
Set your API key in your environment variables.
# .env
ZTLAYER_API_KEY="zt_live_xxxxxxxxxxxxxxxxxxxxxxxx"Initialize the SDK singleton. This should be done once during your application's bootstrap phase.
import { ZTLayer } from '@ztlayer/node';
const security = new ZTLayer({
apiKey: process.env.ZTLAYER_API_KEY,
// Recommended: Set environment so metrics are bucketed correctly
environment: process.env.NODE_ENV || 'development',
failMode: 'open'
});3. Raw HTTP Server Example
If you are building a lightweight microservice using Node's built-in http module, you can wrap the request handler.
import http from 'http';
const server = http.createServer(async (req, res) => {
try {
// 1. Inspect the request before routing
const verdict = await security.inspectHTTP(req);
// 2. Handle the verdict
if (verdict.action === 'block') {
res.writeHead(403, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: 'Blocked by ZTLayer WAF' }));
}
if (verdict.action === 'challenge') {
res.writeHead(401, { 'Content-Type': 'application/json' });
return res.end(JSON.stringify({ error: 'Challenge Required', url: verdict.challengeUrl }));
}
// 3. Request is safe. Proceed with your business logic.
if (req.url === '/api/health') {
res.writeHead(200);
return res.end('OK');
}
res.writeHead(404);
res.end();
} catch (error) {
// In fail-open mode, inspectHTTP will rarely throw, but always catch errors globally
console.error('Security verification failed:', error);
res.writeHead(500);
res.end('Internal Server Error');
}
});
server.listen(3000, () => console.log('Secure server running on port 3000'));4. Fastify Integration
Fastify is supported natively via its plugin architecture. You can register ZTLayer as a pre-handler hook.
import Fastify from 'fastify';
const fastify = Fastify({ logger: true });
// Register the ZTLayer Hook
fastify.addHook('preHandler', async (request, reply) => {
const verdict = await security.inspectFastify(request);
if (verdict.action === 'block') {
// Fastify will automatically halt the request lifecycle
reply.code(403).send({ error: 'Blocked by ZTLayer' });
return reply;
}
});
fastify.get('/api/data', async (request, reply) => {
return { hello: 'world' };
});
fastify.listen({ port: 3000 });Advanced: Excluding Webhooks
If you are receiving Stripe or GitHub webhooks, you may want to bypass the security inspection to avoid accidental blocking of legitimate server-to-server traffic.
fastify.addHook('preHandler', async (request, reply) => {
// Bypass inspection for specific routes
if (request.url.startsWith('/api/webhooks/')) {
return;
}
const verdict = await security.inspectFastify(request);
if (verdict.action === 'block') {
reply.code(403).send({ error: 'Blocked' });
}
});