HapiJS 全局路径前缀
HapiJS global path prefix
我正在写关于 HapiJS 的 API,想知道如何获得全局前缀。例如,所有请求都应发送至:
https://api.mysite.com/v0/...
所以我想将 v0
配置为全局前缀。文档 (here) 似乎没有提到它——在 HapiJS 中有没有好的方法来做到这一点?
如果您将 API 路由逻辑放在 Hapi plugin 中,比如 ./api.js
:
exports.register = function (server, options, next) {
server.route({
method: 'GET',
path: '/hello',
handler: function (request, reply) {
reply('World');
}
});
next();
};
exports.register.attributes = {
name: 'api',
version: '0.0.0'
};
您向服务器注册插件并传递一个可选的路由前缀,该前缀将添加到插件内的所有路由中:
var Hapi = require('hapi');
var server = new Hapi.Server()
server.connection({
port: 3000
});
server.register({
register: require('./api.js')
}, {
routes: {
prefix: '/v0'
}
},
function(err) {
if (err) {
throw err;
}
server.start(function() {
console.log('Server running on', server.info.uri)
})
});
您可以通过启动服务器并访问 http://localhost:3000/v0/hello
.
来验证它是否有效
你总是可以像这样开始你的index.js
if (!global.PREFIX) {
global.PREFIX = '/v0';
}
通过这种方式,您可以在代码中的任何地方访问 PREFIX
这就是您访问 PREFIX 的方式
console.log(PREFIX);
或 var name = PREFIX+ "_somename";
是 hapi 使用插件的方式。
或者,如果您不想创建插件只是为了添加前缀,您可以手动,将前缀添加到所有路由。
例如我做了这样的事情:
var PREFIX = '/v0';
var routes = [/* array with all your root */];
var prefixize = function (route) { route.path = PREFIX + route.path;return route; }
server.route(routes.map(prefixize));
好的一点是,使用这样的东西,您可以执行 express
之类的安装。例如:
var prefixize = function (prefix, route) { route.path = prefix + route.path;return route; }
server.route(adminRoutes.map(prefixize.bind({}, "/admin"))); //currying.
server.route(apiRoutes.map(prefixize.bind({}, "/api")));
我能够使用
让它在所有路线上工作
var server = new Hapi.Server()
...
server.realm.modifiers.route.prefix = '/v0'
server.route(...)
看看hapi-auto-route。此插件自动从目录
注册您的路线
// Directory structure
//
// node_modules/
// routes/
// home.js
// server.js
// package.json
// routes/home.js
'use strict';
module.exports = {
method: 'GET',
path: '/',
handler: (request, h) => 'Hello';
}
// server.js
'use strict';
const Hapi = require('hapi');
const server = Hapi.Server({
port: 3000,
host: 'localhost'
});
const init = async () => {
await server.register(require('hapi-auto-route'));
await server.start();
console.log(`Server is running at: ${server.info.uri}`);
};
process.on('unhandledRejection', (error) => {
console.log(error);
process.exit();
});
init()
并为其添加前缀:
我来晚了,但搜索结果中出现了这个。FWIW,我正在使用这个,建立在 之上。它允许设置多个全局前缀并使用子路由前缀(类似于 Django url 的布局方式)。这是一个包含多个 route.js 文件和 api 路由版本的示例(为清楚起见,路由处理程序已移出):
/departments/routes.js
const { getDepartments, getDepartmentById } = require('./handlers');
module.exports = [
{ method: 'GET', path: '', handler: getDepartments },
{ method: 'GET', path: '/{id}', handler: getDepartmentById }
];
/users/routes.js
const { getUsersV1, getUserByIdV1, getUsersV2, getUserByIdV2 } = require('./handlers');
const userRoutesV1 = [
{ method: 'GET', path: '', handler: getUsersV1 },
{ method: 'GET', path: '/{id}', handler: getUserByIdV1 }
];
const userRoutesV2 = [
{ method: 'GET', path: '', handler: getUsersV2 },
{ method: 'GET', path: '/{id}', handler: getUserByIdV2 }
];
module.exports = { userRoutesV1, userRoutesV2 };
index.js
const Hapi = require('@hapi/hapi');
const departmentRoutes = require('./departments/routes');
const { userRoutesV1, userRoutesV2 } = require('./users/routes');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: 'localhost',
});
const allRoutes = [];
const v1 = '/api/v1/';
const v2 = '/api/v2/';
const prefixer = (routeArray, apiPrefix, subRoutePrefix) => {
routeArray.map(route => {
route.path = `${apiPrefix}${subRoutePrefix}${route.path}`;
allRoutes.push(route);
});
};
prefixer(departmentRoutes, v1, 'departments');
prefixer(userRoutesV1, v1, 'users');
prefixer(userRoutesV2, v2, 'users');
server.route(allRoutes);
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', err => {
console.log(err);
process.exit(1);
});
init();
这是我实现我的方法的方法
我创建了一个辅助函数,它接受一个 Hapi.ServerRoute
的数组,然后映射它并连接前缀,然后 return 数组。
这些片段在 Typescript 中,所以如果您使用 JavaScript 只需去掉类型
// Helper function
export function routerGroup (namespace: string, routes: Hapi.ServerRoute[]) {
return routes.map(r => {
r.path = namespace + r.path
return r
})
}
// Routes declarations
export default routerGroup('/v1/api', [
{
method: 'POST',
path: '/login',
options: {
validate: {
payload: Joi.object({
email: Joi.string().required().email(),
password: Joi.string().required().min(8).max(30)
})
},
auth: false
},
handler: Authentication.adminLogin
}
] as Hapi.ServerRoute[]
)
// Register routes to Hapi server
server.route(
[
...v1Routes,
...
]
)
对于Hapi 19, 20 ...您可以在注册之前简单地用map路径修改路由。
// Example route
const routes = [
{
method: 'GET',
path: '/test',
handler: function (request) {
return {
status: 'success'
};
}
}
];
// transform /test -> /api/test
routes.map((r) => {
r.path = `/api${r.path}`;
return null;
});
// Register
server.route([
...routes
]);
server.realm.modifiers.route.prefix = '/api/v2'
await server.route(yourroutes);
这应该可以正常工作,但是如果您希望能够从您的路由 directory/file Hapi Router 中自动解析所有路由。你可以做这样的事情,这会节省你很多时间。
await server.register({
plugin: HapiRouter,
options: {
routes: "./src/routes/product-routes.js",
},
}, {
routes: {
prefix: "/api/v1"
}
});
您的路由文件应如下所示。
export default [{
method: "GET",
path: "/products",
options: {
tags: ["api", "Products"],
description: "Get All Products",
},
handler: () => {...}
}]
我正在写关于 HapiJS 的 API,想知道如何获得全局前缀。例如,所有请求都应发送至:
https://api.mysite.com/v0/...
所以我想将 v0
配置为全局前缀。文档 (here) 似乎没有提到它——在 HapiJS 中有没有好的方法来做到这一点?
如果您将 API 路由逻辑放在 Hapi plugin 中,比如 ./api.js
:
exports.register = function (server, options, next) {
server.route({
method: 'GET',
path: '/hello',
handler: function (request, reply) {
reply('World');
}
});
next();
};
exports.register.attributes = {
name: 'api',
version: '0.0.0'
};
您向服务器注册插件并传递一个可选的路由前缀,该前缀将添加到插件内的所有路由中:
var Hapi = require('hapi');
var server = new Hapi.Server()
server.connection({
port: 3000
});
server.register({
register: require('./api.js')
}, {
routes: {
prefix: '/v0'
}
},
function(err) {
if (err) {
throw err;
}
server.start(function() {
console.log('Server running on', server.info.uri)
})
});
您可以通过启动服务器并访问 http://localhost:3000/v0/hello
.
你总是可以像这样开始你的index.js
if (!global.PREFIX) {
global.PREFIX = '/v0';
}
通过这种方式,您可以在代码中的任何地方访问 PREFIX
这就是您访问 PREFIX 的方式
console.log(PREFIX);
或 var name = PREFIX+ "_somename";
或者,如果您不想创建插件只是为了添加前缀,您可以手动,将前缀添加到所有路由。
例如我做了这样的事情:
var PREFIX = '/v0';
var routes = [/* array with all your root */];
var prefixize = function (route) { route.path = PREFIX + route.path;return route; }
server.route(routes.map(prefixize));
好的一点是,使用这样的东西,您可以执行 express
之类的安装。例如:
var prefixize = function (prefix, route) { route.path = prefix + route.path;return route; }
server.route(adminRoutes.map(prefixize.bind({}, "/admin"))); //currying.
server.route(apiRoutes.map(prefixize.bind({}, "/api")));
我能够使用
让它在所有路线上工作var server = new Hapi.Server()
...
server.realm.modifiers.route.prefix = '/v0'
server.route(...)
看看hapi-auto-route。此插件自动从目录
注册您的路线// Directory structure
//
// node_modules/
// routes/
// home.js
// server.js
// package.json
// routes/home.js
'use strict';
module.exports = {
method: 'GET',
path: '/',
handler: (request, h) => 'Hello';
}
// server.js
'use strict';
const Hapi = require('hapi');
const server = Hapi.Server({
port: 3000,
host: 'localhost'
});
const init = async () => {
await server.register(require('hapi-auto-route'));
await server.start();
console.log(`Server is running at: ${server.info.uri}`);
};
process.on('unhandledRejection', (error) => {
console.log(error);
process.exit();
});
init()
并为其添加前缀:
我来晚了,但搜索结果中出现了这个。FWIW,我正在使用这个,建立在
/departments/routes.js
const { getDepartments, getDepartmentById } = require('./handlers');
module.exports = [
{ method: 'GET', path: '', handler: getDepartments },
{ method: 'GET', path: '/{id}', handler: getDepartmentById }
];
/users/routes.js
const { getUsersV1, getUserByIdV1, getUsersV2, getUserByIdV2 } = require('./handlers');
const userRoutesV1 = [
{ method: 'GET', path: '', handler: getUsersV1 },
{ method: 'GET', path: '/{id}', handler: getUserByIdV1 }
];
const userRoutesV2 = [
{ method: 'GET', path: '', handler: getUsersV2 },
{ method: 'GET', path: '/{id}', handler: getUserByIdV2 }
];
module.exports = { userRoutesV1, userRoutesV2 };
index.js
const Hapi = require('@hapi/hapi');
const departmentRoutes = require('./departments/routes');
const { userRoutesV1, userRoutesV2 } = require('./users/routes');
const init = async () => {
const server = Hapi.server({
port: 3000,
host: 'localhost',
});
const allRoutes = [];
const v1 = '/api/v1/';
const v2 = '/api/v2/';
const prefixer = (routeArray, apiPrefix, subRoutePrefix) => {
routeArray.map(route => {
route.path = `${apiPrefix}${subRoutePrefix}${route.path}`;
allRoutes.push(route);
});
};
prefixer(departmentRoutes, v1, 'departments');
prefixer(userRoutesV1, v1, 'users');
prefixer(userRoutesV2, v2, 'users');
server.route(allRoutes);
await server.start();
console.log('Server running on %s', server.info.uri);
};
process.on('unhandledRejection', err => {
console.log(err);
process.exit(1);
});
init();
这是我实现我的方法的方法
我创建了一个辅助函数,它接受一个 Hapi.ServerRoute
的数组,然后映射它并连接前缀,然后 return 数组。
这些片段在 Typescript 中,所以如果您使用 JavaScript 只需去掉类型
// Helper function
export function routerGroup (namespace: string, routes: Hapi.ServerRoute[]) {
return routes.map(r => {
r.path = namespace + r.path
return r
})
}
// Routes declarations
export default routerGroup('/v1/api', [
{
method: 'POST',
path: '/login',
options: {
validate: {
payload: Joi.object({
email: Joi.string().required().email(),
password: Joi.string().required().min(8).max(30)
})
},
auth: false
},
handler: Authentication.adminLogin
}
] as Hapi.ServerRoute[]
)
// Register routes to Hapi server
server.route(
[
...v1Routes,
...
]
)
对于Hapi 19, 20 ...您可以在注册之前简单地用map路径修改路由。
// Example route
const routes = [
{
method: 'GET',
path: '/test',
handler: function (request) {
return {
status: 'success'
};
}
}
];
// transform /test -> /api/test
routes.map((r) => {
r.path = `/api${r.path}`;
return null;
});
// Register
server.route([
...routes
]);
server.realm.modifiers.route.prefix = '/api/v2'
await server.route(yourroutes);
这应该可以正常工作,但是如果您希望能够从您的路由 directory/file Hapi Router 中自动解析所有路由。你可以做这样的事情,这会节省你很多时间。
await server.register({
plugin: HapiRouter,
options: {
routes: "./src/routes/product-routes.js",
},
}, {
routes: {
prefix: "/api/v1"
}
});
您的路由文件应如下所示。
export default [{
method: "GET",
path: "/products",
options: {
tags: ["api", "Products"],
description: "Get All Products",
},
handler: () => {...}
}]