【问题标题】:How to make optional params name in express route?如何在快速路线中制作可选参数名称?
【发布时间】:2016-11-22 13:20:21
【问题描述】:

下面是我的路线代码:-

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 但一次只能得到一个。

【问题讨论】:

  • idfilter 只是占位符名称,它们的含义完全取决于您。你不妨称它为:idOrFilter 并使用req.params.idOrFilter 来涵盖这两种情况。
  • 感谢您的回复,但在我的情况下,过滤器参数有 json,我在服务器中处理这个是不同的,即var query; if (req.user.userType == 'super_admin') query = {}; else if (req.user.roleOrder < config.highestRoleOrder) { query = { companyId: req.user.companyId, createdBy: req.user._id }; } if (req.params.id) { query._id = req.params.id; } else if (req.params.filterQuery) { _.merge(query, JSON.parse(req.params.filterQuery)) } Lead.find(query)
  • 也许我不明白你到底想要什么:你希望/server/lead/get/:id?/server/lead/get/:filter? 同时存在?
  • @robertklep 看起来我们这里有一个chameleon question :)
  • @robertklep 是的,我就是这样。

标签: node.js express routes


【解决方案1】:

您在问题中提出的问题不可能以您描述的形式出现。

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

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

您的选择

你这里有几个解决方案:

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

  2. 正如 Robert 在 cmets 中解释的那样,您可以为这两种情况使用一个通用参数。

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

    李>

示例网址:

  • /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') 用于a 列表 对象(可选 filterQuery 作为查询参数传递)

这样您在访问时总是会知道:

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

如果您在此类事情上遵循 REST 约定而不是自己发明,那么您设计路由和处理程序会容易得多,其他人使用您的系统也会容易得多。

您可能还想使用 plural /server/leads 而不是 REST 常见的 /server/lead。这样一来,leads 是一个列表,leads/id 是它的元素之一会更加明显。

更多信息见:

【讨论】:

    【解决方案2】:

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

    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 传递给 URL 中的“过滤器”路由。我强烈建议为此使用 POST 路由,并将 JSON 作为请求正文内容发布。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-27
      • 2019-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-20
      • 2016-04-14
      相关资源
      最近更新 更多