Code Examples
Practical snippets for the APM Node.js connector. More languages coming.
Custom response headers
Use the _headers key inside the second argument of conn.write()
to attach arbitrary HTTP response headers. Any key inside _headers is forwarded
verbatim to the HTTP response.
customHeaders does nothing.
The APM Go server reads a special key called _headers (underscore prefix).
A top-level key named customHeaders containing a nested object is silently
ignored because the server only unpacks string-valued top-level keys and the dedicated
_headers sub-object.
Wrong — customHeaders is silently dropped
// ✗ customHeaders is NOT a recognised key — the Go server ignores it
conn.write(html, {
customHeaders: {
'Cache-Control': 'no-store',
'X-My-Header': 'value',
},
});
Correct — use _headers
// ✓ _headers is the recognised key — every string value becomes a response header
conn.write(html, {
_headers: {
'Cache-Control': 'no-store, no-cache',
'X-My-Header': 'value',
},
});
conn.write(data, opts) spreads opts into the IPC frame:
{"_command":"write", ...opts}. The Go server iterates the frame, skips
underscore-prefixed keys (internal protocol fields), and for the special key
_headers it unpacks the nested object and writes each entry as an HTTP
response header.
Setting cookies
Cookies are set via Set-Cookie inside _headers — exactly like
any other response header. This only works on HTTP connections; on
WebSocket connections the HTTP handshake is already complete by the time your handler
runs, so Set-Cookie in conn.write() has no effect.
function handleRequest(conn) {
if (conn.protocol !== 'http') return; // WS: handshake already done
const cookieName = 'session';
const cookieValue = generateToken();
const cookieStr = [
`${cookieName}=${cookieValue}`,
'Path=/',
'HttpOnly',
'SameSite=Strict',
/* 'Secure' — add when behind HTTPS */
].join('; ');
conn.write(html, {
_headers: { 'Set-Cookie': cookieStr },
});
}
Set-Cookie value, or by serving a redirect
through a second request that sets additional cookies.
Status codes
Pass _status (a number) alongside _headers to control the HTTP
response status code. The default is 200.
// 404 Not Found
conn.write('<h1>Not found</h1>', { _status: 404 });
// 301 redirect
conn.write('', {
_status: 301,
_headers: { 'Location': '/new-path' },
});
// 200 with custom content-type and cache header
conn.write(jsonString, {
_status: 200,
_headers: {
'Content-Type': 'application/json',
'Cache-Control': 'max-age=60',
},
});
Reading cookies
APM parses the incoming Cookie header for you. Use conn.cookies
(an object keyed by cookie name) or conn.headers.cookie (the raw string) on
both HTTP and WebSocket connections.
function handleRequest(conn) {
// conn.cookies is pre-parsed: { session: 'abc123', theme: 'dark', ... }
const sessionId = conn.cookies['session'];
if (!sessionId) {
// No session cookie — send login page
conn.write(loginPage, { _status: 401 });
return;
}
// Validate sessionId against your store...
const user = sessions.get(sessionId);
if (!user) {
conn.write(loginPage, { _status: 401 });
return;
}
conn.write(dashboardPage(user));
}
conn.cookies is available on both HTTP (conn.protocol === 'http')
and WebSocket (conn.protocol === 'ws') connections — APM parses the cookie
header from the initial HTTP upgrade request and attaches it to the session object.