HapiJS全局路径前缀

时间:2015-01-10 00:10:34

标签: node.js url-routing hapijs

我在HapiJS上编写API,并想知道如何获得全局前缀。例如,所有请求都应该发送到:

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

所以我想将v0配置为全局前缀。文档(here)似乎没有提到它 - 在HapiJS中有一个很好的方法吗?

8 个答案:

答案 0 :(得分:16)

如果您将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来验证此方法。

答案 1 :(得分:9)

我能够通过

让它适用于所有路线
var server = new Hapi.Server()
...
server.realm.modifiers.route.prefix = '/v0'
server.route(...)

答案 2 :(得分:3)

Matt Harrisson's answer是使用插件执行此操作的 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")));

答案 3 :(得分:1)

你总是可以像这样开始你的index.js

if (!global.PREFIX) {
  global.PREFIX = '/v0';
}

这样你的代码中的任何地方都可以访问PREFIX

这就是你如何访问PREFIX

console.log(PREFIX);var name = PREFIX+ "_somename";

答案 4 :(得分:0)

看看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()

并添加前缀:

答案 5 :(得分:0)

我参加这个聚会很晚,但这出现在搜索结果中。FWIW,我使用的是AdrieanKhisbe’s answer的基础。它允许设置多个全局前缀并使用子路由前缀(类似于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();

答案 6 :(得分:0)

这是我实施我的方式

我创建了一个辅助函数,该函数接受一个Hapi.ServerRoute数组,然后通过其映射并连接前缀,然后返回该数组。

代码段位于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,
    ...
  ]
)

答案 7 :(得分:0)

对于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
]);