如何在快速路线中制作可选的参数名称?

时间:2016-11-22 13:20:21

标签: node.js express routes

以下是我的路线代码: -

app.get('/server/lead/get/:id?', leadCtrl.get);
app.get('/server/lead/filter/:filterQuery', leadCtrl.get);

如上所示,我使用不同的路径来访问相同的控制器方法leadCtrl.get

现在,我想要路线app.get('/server/lead/get/:id?:filter?', leadCtrl.get);之类的东西。所以,我可以req.params.idreq.params.filter获得参数,但一次只能获得一个参数。

2 个答案:

答案 0 :(得分:3)

您在问题中提到的内容无法以您描述的形式提供。

  

现在,我想要像路线这样的东西   app.get(' / server / lead / get /:id?:filter?',leadCtrl.get);.所以,我可以得到   params req.params.id或req.params.filter但只有一个在a   时间。

您的路由器无法区分这两个参数。如果它收到/server/lead/get/X的请求那么什么是X?过滤器还是ID?

您的选择

这里你的解决方案很少:

  1. 您可以像以前一样继续使用两条路线。

  2. 您可以使用罗伯特在评论中解释的两种情况的通用参数。

  3. 或者您可以使用我认为完美的解决方案 - 命名查询参数 - 只需使用路由/server/lead/get并使用查询参数传递id和过滤器。

  4. 示例网址:

    • /server/lead/get?id=xxx
    • /server/lead/get?filterQuery=xxx

    您只需要在处理程序中确保一次只设置其中一个,例如:

    if (req.query.id && req.query.filterQuery) {
      // respond with error
    }
    

    如果您有app.get('/server/lead/get/:id?')路由,您甚至可以将两者混合在一起,您可以在路由中使用id,并将filterQuery作为查询参数。现在URL将是:

    • /server/lead/get/xxx(代表身份)
    • /server/lead/get?filterQuery=xxx(用于过滤)

    有关详细信息,请参阅:http://expressjs.com/en/api.html#req.query

    更好的方式

    如果您遵循一些 REST约定,则可以使用:

    • app.get(' / server / lead /:id')一个对象的ID(可选)
    • app.get(' / server / lead')用于列表对象(可选的filterQuery作为查询参数传递)

    这样,当你访问时,你总会知道:

    • /server/lead/xxx - 然后是一个对象ID = xxx
    • /server/lead - 然后它列表包含任何对象
    • /server/lead?filterQuery=xxx - 然后它列表与查询匹配的对象

    如果您按照REST惯例执行此类操作而不是发明自己的约定,那么设计路由和处理程序会更加容易,而其他人也可以更轻松地使用您的系统。

    您可能还想使用复数 /server/leads而不是/server/lead这是REST常见的。这样,leads是一个列表,而leads/id是其中的一个元素,这将更加明显。

    有关详细信息,请参阅:

答案 1 :(得分:3)

您必须意识到以下两条路线完全匹配

app.get('/server/lead/get/:id?',     leadCtrl.get);
app.get('/server/lead/get/:filter?', leadCtrl.get);

Express并不关心您如何命名占位符,因此对/server/lead/get/SOMEVALUE的任何请求将始终与第一个(:id}的请求匹配。

您可以自己添加区别,只允许参数匹配特定的正则表达式。从您的代码看,:id看起来应该与MongoDB ObjectId匹配,因此您可以为这些创建特定的匹配项:

app.get('/server/lead/get/:id([a-fA-F0-9]{24})?', leadCtrl.get);

如果SOMEVALUE与ObjectId匹配,则会调用leadCtrl.get并填充req.params.id。如果您还为“其余”添加了另一个路由器,您还可以涵盖req.params.filter案例:

app.get('/server/lead/get/:filter?', leadCtrl.get);

顺便说一下:你说你在网址中将JSON传递给“过滤”路由。我强烈建议使用POST路由,并将JSON作为请求正文内容发布。