Suppose I want to have REST endpoints which look roughly like this:
/projects/
/projects/project_id
/projects/project_id/items/
/projects/project_id/items/item
There isn't great information about such a basic requirement. Currently, I am doing the following & it works well.
Step 1: Contain the routes in a plugin, as so:
// server.js
const server = Hapi.server({ ... })
await server.register(require('./routes/projects'), { routes: { prefix: '/projects' } })
Step 2: Register an ext
within the scope of that plugin.
// routes/projects/index.js
module.exports = {
name: 'projects',
async register(server) {
server.route({
method: 'get',
path: '/', // note: you don't need to prefix with `projects`
async handler(request, h) {
return [ ... ]
}
})
server.route({
method: 'get',
path: '/{projectId}', // note: you don't need to prefix with `projects`
async handler(request, h) {
return { ... }
}
})
server.ext({
// https://hapijs.com/api#request-lifecycle
type: 'onPostAuth',
options: {
// `sandbox: plugin` will scope this ext to this plugin
sandbox: 'plugin'
},
async method (request, h) {
// here you can do things as `pre` steps to all routes, for example:
// verify that the project `id` exists
if(request.params.projectId) {
const project = await getProjectById(request.params.projectId)
if(!project) {
throw Boom.notFound()
}
// Now request.params.project can be available to all sub routes
request.params.project = project
}
return h.continue
}
})
}
}
This has been as close to I have been able to get to recreating Express Router functionality.