【问题标题】:Why do chained get(), post() and put() methods not require the path argument?为什么链式 get()、post() 和 put() 方法不需要路径参数?
【发布时间】:2018-10-19 05:42:04
【问题描述】:

我正在从各种教程中学习 express,并且有一个可以在本地运行的应用程序,但我想更好地了解代码的每个部分的作用。

我对此处app.route() 部分中的示例感到有些困惑:

https://expressjs.com/en/guide/routing.html

app.route('/book')
  .get(function (req, res) {
    res.send('Get a random book')
  })
  .post(function (req, res) {
    res.send('Add a book')
  })
  .put(function (req, res) {
    res.send('Update the book')
  })

我可以看到app 等于express(),这是记录在here 的顶级函数。

我可以看到.get()post()put() 方法链接到route() 方法,记录在here

我感到困惑的是,文档声明 .get()post()put() 方法的参数采用以下格式:

app.get(path, callback [, callback ...])
app.post(path, callback [, callback ...])
app.put(path, callback [, callback ...])

为什么链接的.get()post()put() 方法不需要path 参数,而是有一个单数函数作为从Request(又名req)返回值的参数和Response(又名res)对象参数?

我显然遗漏了一些简单的东西,所以当直接从app(例如app.get())和从route()(例如app.route('/book').get())调用时,指向文档的指针可以帮助我更好地理解这些方法之间的区别不胜感激。

编辑:基本上,我想知道是否有文档定义了从路由对象调用时.get()post()put() 方法所需的参数格式从调用app.route("/book") 返回,因为它似乎不是记录的内容,即path, callback [, callback ...]

【问题讨论】:

    标签: node.js express routes


    【解决方案1】:

    app.route()

    根据文档,app.route 方法:

    返回单个路由的实例,然后您可以使用它来处理带有可选中间件的 HTTP 动词。使用 app.route() 来避免重复的路由名称(从而避免拼写错误)。

    这意味着app.route() 只接受路径并返回route object。它将具有所有 http 动词方法来处理针对一条路径的中间件,getpostdeletepostputpatch 等。

    为什么?

    简单地拥有具有相同路径但不同 HTTP 请求的路由。喜欢:

    app.route('/books')
      .get() // To get the list of objects
      .post() // To save a new book.
    

    单独的 HTTP 方法

    另一方面,express 在 app 上提供了单独的方法来处理 HTTP 请求。喜欢app.get()app.post()app.delete()

    根据 post route 的文档:HTTP POST 请求到具有指定回调函数的指定路径。

    为什么?

    对于多个 HTTP 请求没有一个路径的情况。比方说:

    app.delete('/books/:bookId/comments/:commentId', function(){});
    

    上述路由是一种单路由,仅用于删除某本书的特定评论。

    我希望我能够清除差异。

    文档参考链接:https://expressjs.com/en/4x/api.html#router.route

    编辑:

    由于没有适当的文档可用列出路由对象提供的方法: 欲了解更多信息,请将 github 的链接添加到 express 路由器。

    https://github.com/expressjs/express/blob/master/lib/router/route.js

    这里看下面 express 路由器的代码,它在所有方法上添加了处理程序。

    methods.forEach(function(method){
      Route.prototype[method] = function(){
        var handles = flatten(slice.call(arguments));
    
        for (var i = 0; i < handles.length; i++) {
          var handle = handles[i];
    
          if (typeof handle !== 'function') {
            var type = toString.call(handle);
            var msg = 'Route.' + method + '() requires a callback function but got a ' + type
            throw new Error(msg);
          }
    
          debug('%s %o', method, this.path)
    
          var layer = Layer('/', {}, handle);
          layer.method = method;
    
          this.methods[method] = true;
          this.stack.push(layer);
        }
    
        return this;
      };
    });
    

    在顶部的这个文件中,它有:

    var methods = require('methods');

    方法:https://github.com/jshttp/methods

    因此,链式方法所需的参数是unlimited functions 作为请求handlers/middlewares

    【讨论】:

    • 是否有文档定义了route object 提供的方法以及所需的参数格式? app.get() 的文档似乎不适用于 app.route("/book").get() - 前者需要 path, callback [, callback ...] 作为 get() 的参数,而后者只有一个函数 get() 的参数。这就是为什么我要问这个问题Why do the chained .get(), post() and put() methods not require the path argument?
    • 嘿,我已经更新了我的答案并添加了参考链接。问题是文档中没有明确列出路由器对象上的方法的 API 参考。但根据文档。 route 对象将具有所有 HTTP 动词方法。
    • 我从 express 的 github 代码中添加了更多对我的答案的引用
    • var handles = flatten(slice.call(arguments)); 表示您可以将多个方法传递给它。链接的 HTTP 方法的参数只有 handlers/functions
    • 因此,这些方法所需的参数格式是“无限函数”,它们都具有可用作参数的reqres 对象?
    【解决方案2】:

    链式方法的要点是它们具有相同的路径。

    所以你可以这样写:

    app.route('/book')
      .get(function (req, res) {
        res.send('Get a random book')
      })
      .post(function (req, res) {
        res.send('Add a book')
      })
      .put(function (req, res) {
        res.send('Update the book')
      })
    

    而不是

      app.get('/book', function (req, res) {
        res.send('Get a random book')
      });
      app.post('/book', function (req, res) {
        res.send('Add a book')
      });
      app.put('/book', function (req, res) {
        res.send('Update the book')
      });
    

    这意味着如果您更改端点,它会针对所有方法进行更改,您不能在一种方法中写错字...

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-08-26
      • 2017-05-07
      • 1970-01-01
      • 1970-01-01
      • 2020-09-02
      • 2015-02-12
      • 2010-10-28
      • 2019-12-29
      相关资源
      最近更新 更多