HTTP Server framework for Node.js with built-in authentication, validation, caching, logging, and plugin architecture
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
Rich request object with parsed headers, payload, query parameters, and extensive metadata for handling HTTP requests in @hapi/hapi.
The request object contains comprehensive information about the incoming HTTP request.
interface Request {
/** Application-specific request state */
app: object;
/** Authentication information */
auth: AuthInfo;
/** Request-specific event emitter */
events: Events;
/** Request headers as key-value pairs */
headers: { [key: string]: string };
/** Request information and metadata */
info: RequestInfo;
/** JSONP callback parameter if present */
jsonp?: string;
/** Array of request log entries */
logs: LogEntry[];
/** HTTP method in lowercase */
method: string;
/** Content MIME type */
mime: string;
/** Original request properties before processing */
orig: object;
/** Path parameters extracted from route pattern */
params: { [key: string]: string };
/** Path parameters as ordered array */
paramsArray: string[];
/** Request path */
path: string;
/** Parsed request payload */
payload: any;
/** Plugin-specific request state */
plugins: object;
/** Pre-handler method results */
pre: object;
/** Pre-handler response objects */
preResponses: object;
/** Query string parameters */
query: { [key: string]: string };
/** Raw Node.js request and response objects */
raw: { req: IncomingMessage; res: ServerResponse };
/** Response object */
response: Response;
/** Route information */
route: RouteInfo;
/** Server instance handling the request */
server: Server;
/** Cookie state values */
state: { [key: string]: any };
}Detailed metadata about the request including timing, network info, and processing state.
interface RequestInfo {
/** Request accept encoding header parsed */
acceptEncoding: string;
/** Whether request was handled by CORS */
cors: {
isOriginMatch: boolean;
isAccessControlRequestHeaders: boolean;
isAccessControlRequestMethod: boolean;
};
/** Request completion timestamp */
completed?: number;
/** Request hostname */
hostname: string;
/** Unique request identifier */
id: string;
/** Request received timestamp */
received: number;
/** Request referrer header */
referrer: string;
/** Remote client IP address */
remoteAddress: string;
/** Remote client port */
remotePort: number;
/** Whether response has been sent */
responded: number;
}Usage Examples:
server.route({
method: 'GET',
path: '/request-info',
handler: (request, h) => {
return {
method: request.method,
path: request.path,
userAgent: request.headers['user-agent'],
remoteAddress: request.info.remoteAddress,
received: new Date(request.info.received),
id: request.info.id
};
}
});Authentication state and credentials for the current request.
interface AuthInfo {
/** Whether request is authenticated */
isAuthenticated: boolean;
/** Authentication credentials */
credentials?: AuthCredentials;
/** Authentication strategy used */
strategy?: string;
/** Authentication mode */
mode: 'required' | 'optional' | 'try';
/** Authentication error if failed */
error?: Error;
/** Authentication artifacts */
artifacts?: object;
}
interface AuthCredentials {
/** User identifier */
user?: string;
/** User scope/permissions */
scope?: string[];
/** Additional credential data */
[key: string]: any;
}Usage Examples:
server.route({
method: 'GET',
path: '/profile',
options: {
auth: 'session'
},
handler: (request, h) => {
if (request.auth.isAuthenticated) {
return {
user: request.auth.credentials.user,
scope: request.auth.credentials.scope
};
}
return { error: 'Not authenticated' };
}
});Access to path parameters, query parameters, and payload data.
// Path parameters from route pattern
request.params: { [key: string]: string };
request.paramsArray: string[];
// Query string parameters
request.query: { [key: string]: string };
// Request payload (parsed based on content-type)
request.payload: any;Usage Examples:
// Route with path parameters
server.route({
method: 'GET',
path: '/users/{userId}/posts/{postId}',
handler: (request, h) => {
return {
userId: request.params.userId,
postId: request.params.postId,
paramsArray: request.paramsArray // ['userId_value', 'postId_value']
};
}
});
// Route with query parameters
server.route({
method: 'GET',
path: '/search',
handler: (request, h) => {
return {
query: request.query.q,
page: parseInt(request.query.page) || 1,
limit: parseInt(request.query.limit) || 10
};
}
});
// Route with payload
server.route({
method: 'POST',
path: '/api/data',
handler: (request, h) => {
console.log('Content-Type:', request.mime);
console.log('Payload:', request.payload);
return { received: request.payload };
}
});Methods available on the request object for manipulating the request.
/**
* Update the request URL and re-parse path and query
* @param url - New URL to set
*/
setUrl(url: string): void;
/**
* Update the request method
* @param method - New HTTP method
*/
setMethod(method: string): void;
/**
* Generate a response object
* @param source - Response source/payload
* @param options - Response options
* @returns Response object
*/
generateResponse(source: any, options?: object): Response;
/**
* Log a request-specific event
* @param tags - String or array of tags
* @param data - Optional event data
*/
log(tags: string | string[], data?: any): void;
/**
* Check if the request is still active (not aborted)
* @returns True if request is still active
*/
active(): boolean;Usage Examples:
server.route({
method: 'POST',
path: '/redirect-and-log',
handler: (request, h) => {
// Log request event
request.log(['info', 'handler'], 'Processing redirect request');
// Modify request (rarely needed)
if (request.query.newPath) {
request.setUrl(`/api${request.query.newPath}`);
}
return {
message: 'Request processed',
newPath: request.path
};
}
});
// Listen to request logs
server.events.on('request', (request, event, tags) => {
if (tags.info) {
console.log(`Request ${request.info.id}: ${event.data}`);
}
});Access to cookie state values set by the server.
// Cookie state values parsed from request
request.state: { [key: string]: any };Usage Examples:
// Set up cookie state definition
server.state('session', {
ttl: 24 * 60 * 60 * 1000, // 1 day
isSecure: true,
isHttpOnly: true,
encoding: 'base64json'
});
server.route({
method: 'GET',
path: '/session-info',
handler: (request, h) => {
const session = request.state.session;
if (session) {
return {
sessionId: session.id,
userId: session.userId,
expires: session.expires
};
}
return { message: 'No session found' };
}
});Request-specific event emitter for handling request lifecycle events.
// Request events (EventEmitter interface)
request.events.on(event: string, listener: Function): void;
request.events.emit(event: string, ...args: any[]): boolean;Usage Examples:
server.route({
method: 'GET',
path: '/event-demo',
handler: (request, h) => {
// Listen to request events
request.events.on('peek', (chunk) => {
console.log('Peeked at chunk:', chunk.length, 'bytes');
});
request.events.on('finish', () => {
console.log('Request finished');
});
return { message: 'Event demo' };
}
});interface RouteInfo {
/** Route ID if specified */
id?: string;
/** Route method */
method: string;
/** Route path pattern */
path: string;
/** Route virtual host */
vhost?: string[];
/** Route realm */
realm: Realm;
/** Route settings */
settings: RouteOptions;
/** Route fingerprint hash */
fingerprint: string;
}
interface LogEntry {
/** Log timestamp */
timestamp: number;
/** Log tags */
tags: string[];
/** Log data */
data?: any;
/** Log channel */
channel: string;
}
interface Realm {
/** Parent realm */
parent?: Realm;
/** Plugin name */
plugin: string;
/** Plugin options */
pluginOptions: object;
/** Realm plugins */
plugins: object;
/** Realm settings */
settings: {
bind?: object;
files: {
relativeTo?: string;
};
};
}