Node.js HapiJS全局路径前缀

Node.js HapiJS全局路径前缀,node.js,url-routing,hapijs,Node.js,Url Routing,Hapijs,我正在写一个关于HapiJS的API,想知道如何获得一个全局前缀。例如,所有请求均应发送至: https://api.mysite.com/v0/... 因此,我想将v0配置为全局前缀。文档()似乎没有提到这一点——在HapiJS中有没有一个好方法可以做到这一点?如果您将API路由逻辑放在 exports.register = function (server, options, next) { server.route({ method: 'GET',

我正在写一个关于HapiJS的API,想知道如何获得一个全局前缀。例如,所有请求均应发送至:

https://api.mysite.com/v0/...

因此,我想将
v0
配置为全局前缀。文档()似乎没有提到这一点——在HapiJS中有没有一个好方法可以做到这一点?

如果您将API路由逻辑放在

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';
}
这样,代码中的任何地方都可以访问前缀

这就是访问前缀的方式

console.log(前缀)
var name=前缀+“_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(...)
看一看。这个插件可以自动从一个目录注册你的路由

//目录结构
// 
//节点单元/
//路线/
//home.js
//server.js
//package.json
//routes/home.js
"严格使用",;
module.exports={
方法:“GET”,
路径:“/”,
handler:(请求,h)=>“你好”;
}
//server.js
"严格使用",;
常数Hapi=要求('Hapi');
const server=Hapi.server({
港口:3000,
主机:“localhost”
});
const init=async()=>{
等待服务器。注册(需要('hapi-auto-route');
等待server.start();
log(`Server正在运行:${Server.info.uri}`);
};
process.on('unhandledRejection',(错误)=>{
console.log(错误);
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 }
];
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 };
/users/routes.js

const { getDepartments, getDepartmentById } = require('./handlers');

module.exports = [
  { method: 'GET', path: '', handler: getDepartments },
  { method: 'GET', path: '/{id}', handler: getDepartmentById }
];
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();

下面是我如何实现我的

我创建了一个helper函数,它接受一个数组
Hapi.ServerRoute
,然后映射它,连接前缀,然后返回数组

这些代码段是在Typescript中的,因此如果您使用JavaScript,只需去掉这些类型

//Helper函数
导出函数routerGroup(命名空间:字符串,路由:Hapi.ServerRoute[]){
返回路线图(r=>{
r、 path=名称空间+r.path
返回r
})
}
//路由声明
导出默认路由组(“/v1/api”[
{
方法:“POST”,
路径:'/login',
选项:{
验证:{
有效载荷:Joi.object({
电子邮件:Joi.string().required().email(),
密码:Joi.string().required().min(8)。max(30)
})
},
作者:错
},
处理程序:Authentication.adminLogin
}
]作为Hapi.ServerRoute[]
)
//注册到Hapi服务器的路由
服务器路由(
[
…路线,
...
]
)

针对Hapi 19、20。。。在注册之前,您只需使用地图路径修改路线即可

// 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='/v0'
进行设置,但不能通过嵌套选项进行设置,如您所示。你确定你的方法有效吗?是的,我刚刚用Hapi 8测试过。但此前缀选项仅在注册单个插件时可用。因此,如果您注册了多个插件,它将不起作用。@MattHarrison使用多插件免责声明更新您的答案可能是个好主意:)这对多个插件不起作用。。80%的hapi堆栈将具有哪一个?现在您可以为每个插件指定前缀选项。或者干脆用胶水吧,这是正确的答案,因为马特·哈里森的答案不适用于多个插件——大多数人都会有多个插件。