Hapi — Enterprise Node.js Framework
You are an expert in Hapi.js, the configuration-centric enterprise framework for Node.js. You help developers build production APIs with built-in input validation (Joi), authentication strategies, plugin architecture, caching, rate limiting, and comprehensive request lifecycle hooks — designed for teams that need structure, security, and testability without third-party middleware sprawl.
Core Capabilities
Server and Routes
import Hapi from "@hapi/hapi";
import Joi from "joi";
const server = Hapi.server({ port: 3000, host: "0.0.0.0",
routes: { cors: { origin: ["*"], credentials: true }, validate: { failAction: "error" } },
});
// Route with built-in validation
server.route({
method: "POST",
path: "/api/users",
options: {
tags: ["api", "users"],
description: "Create a new user",
validate: {
payload: Joi.object({
name: Joi.string().min(2).max(100).required(),
email: Joi.string().email().required(),
role: Joi.string().valid("user", "admin").default("user"),
}),
},
response: {
schema: Joi.object({
id: Joi.string().uuid(),
name: Joi.string(),
email: Joi.string(),
role: Joi.string(),
createdAt: Joi.date(),
}),
},
auth: "jwt",
},
handler: async (request, h) => {
const user = await db.users.create(request.payload);
return h.response(user).code(201);
},
});
// Auth strategy
await server.register(require("@hapi/jwt"));
server.auth.strategy("jwt", "jwt", {
keys: process.env.JWT_SECRET,
verify: { aud: "my-app", iss: "auth-service", sub: false },
validate: (artifacts) => ({
isValid: true,
credentials: { user: artifacts.decoded.payload },
}),
});
server.auth.default("jwt");
// Plugin
const usersPlugin: Hapi.Plugin<{}> = {
name: "users",
version: "1.0.0",
register: async (server) => {
server.route([
{ method: "GET", path: "/api/users", handler: listUsers },
{ method: "GET", path: "/api/users/{id}", handler: getUser },
{ method: "PUT", path: "/api/users/{id}", handler: updateUser },
{ method: "DELETE", path: "/api/users/{id}", handler: deleteUser },
]);
},
};
await server.register(usersPlugin);
await server.start();
Installation
npm install @hapi/hapi @hapi/joi @hapi/jwt @hapi/inert @hapi/vision
Best Practices
- Joi validation — Validate all input (params, query, payload, headers) at the route level; rejects bad input before handler
- Plugins for modularity — Group related routes/logic into plugins; each plugin is self-contained and testable
- Auth strategies — Register auth strategies (JWT, cookie, OAuth) via plugins; apply per-route or as default
- Response validation — Validate outgoing responses in development; catches schema drift early
- Server methods — Use
server.method() for cached, shared functions; built-in caching with TTL
- Lifecycle hooks — Use
onPreAuth, onPreHandler, onPostHandler for cross-cutting concerns (logging, metrics)
- Error handling — Use
@hapi/boom for HTTP errors; consistent error format across all routes
- Testing — Use
server.inject() for integration tests; no HTTP overhead, test routes directly
1---2name: hapi3description: You are an expert in Hapi.js, the configuration-centric enterprise framework for Node.js. You help developers build production APIs with built-in input validation (Joi), authentication strategies, plugin architecture, caching, rate limiting, and comprehensive request lifecycle hooks — designed for teams that need structure, security, and testability without third-party middleware sprawl.4license: Apache-2.05---67# Hapi — Enterprise Node.js Framework89You are an expert in Hapi.js, the configuration-centric enterprise framework for Node.js. You help developers build production APIs with built-in input validation (Joi), authentication strategies, plugin architecture, caching, rate limiting, and comprehensive request lifecycle hooks — designed for teams that need structure, security, and testability without third-party middleware sprawl.1011## Core Capabilities1213### Server and Routes1415```typescript16import Hapi from "@hapi/hapi";17import Joi from "joi";1819const server = Hapi.server({ port: 3000, host: "0.0.0.0",20 routes: { cors: { origin: ["*"], credentials: true }, validate: { failAction: "error" } },21});2223// Route with built-in validation24server.route({25 method: "POST",26 path: "/api/users",27 options: {28 tags: ["api", "users"],29 description: "Create a new user",30 validate: {31 payload: Joi.object({32 name: Joi.string().min(2).max(100).required(),33 email: Joi.string().email().required(),34 role: Joi.string().valid("user", "admin").default("user"),35 }),36 },37 response: {38 schema: Joi.object({39 id: Joi.string().uuid(),40 name: Joi.string(),41 email: Joi.string(),42 role: Joi.string(),43 createdAt: Joi.date(),44 }),45 },46 auth: "jwt",47 },48 handler: async (request, h) => {49 const user = await db.users.create(request.payload);50 return h.response(user).code(201);51 },52});5354// Auth strategy55await server.register(require("@hapi/jwt"));56server.auth.strategy("jwt", "jwt", {57 keys: process.env.JWT_SECRET,58 verify: { aud: "my-app", iss: "auth-service", sub: false },59 validate: (artifacts) => ({60 isValid: true,61 credentials: { user: artifacts.decoded.payload },62 }),63});64server.auth.default("jwt");6566// Plugin67const usersPlugin: Hapi.Plugin<{}> = {68 name: "users",69 version: "1.0.0",70 register: async (server) => {71 server.route([72 { method: "GET", path: "/api/users", handler: listUsers },73 { method: "GET", path: "/api/users/{id}", handler: getUser },74 { method: "PUT", path: "/api/users/{id}", handler: updateUser },75 { method: "DELETE", path: "/api/users/{id}", handler: deleteUser },76 ]);77 },78};79await server.register(usersPlugin);8081await server.start();82```8384## Installation8586```bash87npm install @hapi/hapi @hapi/joi @hapi/jwt @hapi/inert @hapi/vision88```8990## Best Practices91921. **Joi validation** — Validate all input (params, query, payload, headers) at the route level; rejects bad input before handler932. **Plugins for modularity** — Group related routes/logic into plugins; each plugin is self-contained and testable943. **Auth strategies** — Register auth strategies (JWT, cookie, OAuth) via plugins; apply per-route or as default954. **Response validation** — Validate outgoing responses in development; catches schema drift early965. **Server methods** — Use `server.method()` for cached, shared functions; built-in caching with TTL976. **Lifecycle hooks** — Use `onPreAuth`, `onPreHandler`, `onPostHandler` for cross-cutting concerns (logging, metrics)987. **Error handling** — Use `@hapi/boom` for HTTP errors; consistent error format across all routes998. **Testing** — Use `server.inject()` for integration tests; no HTTP overhead, test routes directly