【问题标题】:Odd behavior while calling ExpressJS REST route调用 ExpressJS REST 路由时的奇怪行为
【发布时间】:2016-06-15 12:00:29
【问题描述】:

我正在制作一个简单的 REST 服务器,它包含 TMDb 的 API。我正在使用MovieDB Node 模块,它具有通过提供 API 密钥直接调用 TMDb 的 API 的功能。

我有以下应用程序文件夹结构。

myproject
|
---configuration.json
---index.js
---app.js
---/routes
     |
     --- index.js
     --- /movie
           |
           --- index.js

myproject/index.js 中,我有一个简单地启动 Express 服务器的脚本,app.js 是我正在初始化路由的地方。

我的项目/app.js

以下是路由的初始化方式。

var myApp = require("express")(),
    configuration = require("./configuration.json");

myApp.locals.tmdbApiKey = configuration.tmdbApiKey;
myApp.use('/api', require('./routes'));

如上所示,服务器的 API 根为 localhost:9000/api/(我在端口 9000 上运行它)。

myproject/routes/index.js

这是我为movie 加载路线的方式。

var router = require('express').Router();
router.use('/movie', require('./movie'));

myproject/routes/movie/index.js

最后,我定义了如下端点。

var router = require('express').Router();

router.get('/genrelist', function(req, res) {
    var tmdb = require('moviedb')(req.app.locals.tmdbApiKey);

    tmdb.genreList(function(err, tmdbRes) {
        if (err)
            res.send(err);

        res.json(tmdbRes);
    });
});

---
---

用法

现在,调用http://localhost:9000/api/movie/genrelist 应该通过moviedbgenreList() 方法向我回复TMDb API 提供的流派列表,以防我对路线和路线图的理解是正确的。

但是,我收到了以下回复。

{
  "original": null,
  "response": {
    "req": {
      "method": "GET",
      "url": "https://api.themoviedb.org/3/movie/genrelist"
    },
    "header": {
      "access-control-allow-origin": "*",
      "cache-control": "public, max-age=28800",
      "content-type": "application/json;charset=utf-8",
      "date": "Wed, 15 Jun 2016 11:33:51 GMT",
      "etag": "\"37a6259cc0c1dae299a7866489dff0bd\"",
      "server": "openresty",
      "status": "404 Not Found",
      "x-memc": "MISS",
      "x-memc-age": "0",
      "x-memc-expires": "28800",
      "x-memc-key": "35bba1a0c9464e4e471cdb466209d8b3",
      "x-ratelimit-limit": "40",
      "x-ratelimit-remaining": "38",
      "x-ratelimit-reset": "1465990436",
      "content-length": "84",
      "connection": "Close"
    },
    "status": 404,
    "text": "{\"status_code\":34,\"status_message\":\"The resource you requested could not be found.\"}"
  },
  "status": 404
}

如果您看到 response.req.url 的值,它会尝试调用 https://api.themoviedb.org/3/movie/genrelist,这显然是不正确的,因为 TMDb API 没有任何此类端点。

但是,如果我将myproject/routes/movie/index.js 中的router.get 更改为如下内容:

var router = require('express').Router();

router.get('/top_rated', function(req, res) {
    var tmdb = require('moviedb')(req.app.locals.tmdbApiKey);

    tmdb.miscTopRatedMovies(function(err, tmdbRes) {
        if (err)
            res.send(err);

        res.json(tmdbRes);
    });
});

它工作得很好,请注意我还将呼叫从genreList() 更改为miscTopRatedMovies()。令人震惊的是,如果我按原样继续调用genreList(),那么它还会检索top_rated 电影的列表。

甚至可怕的部分是我在 GET 方法中执行 console.log() 并且它没有记录任何内容。如果我在 GET 中设置断点,即使使用 node-debug 调试服务器也不会中断执行。所以我觉得我通过 REST 客户端的 REST 调用被直接转换为 TMDb API 调用(可能是由于相同的 REST 签名),而 MovieDB 根本没有被调用,不过我不是 100% 确定。

因此,为了确定 MovieDB 模块本身是否有问题,我创建了直接使用 MovieDB 的简单 JS 文件,并使用node 命令运行它,它适用于我正在使用的所有方法。

那么我在这里做错了什么?

感谢任何帮助。

【问题讨论】:

  • 你在使用 webstorm 吗?由于 webstorm 缓存,我有过类似的怪异 WTF 时刻
  • @pulse0ne 不,我正在使用 Atom 编辑器和终端运行和调试。

标签: node.js api rest express themoviedb-api


【解决方案1】:

我发现了问题所在,而且很愚蠢。

在我的电影路线中,我有一个终点,如下所示。

router.get('/:movieId', function(req, res) {
    // Call tmdb.movieInfo()
});

其余端点也以/开头,如下。

router.get('/popular', function(req, res) {
    // Call tmdb.movieInfo()
});

很明显,这是一个糟糕的设计,会引起麻烦,因为/:movieId会在传递有效的电影ID时被调用,但我还有其他使用关键字的点(与TMDb完全相同),所以当我在/popular 上尝试了GET,MovieDB 内部调用了由TMDb 确定的API(/api/movie/popular 也是TMDb 的有效端点),因此我得到了正确的结果。

但是,如果我在 /genres 上执行 GET,我的 API 将单词 genres 认为是 /:movieId,因为签名相同,并且由于不存在这样的 ID,所以它失败了。

我现在已将我的终点更正为

router.get('/info/:movieId', function(req, res) {
    // Call tmdb.movieInfo()
});

一切都按预期进行。

经验教训,在涉及参数值和关键字的地方永远不会有相同的端点。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 2014-10-23
    • 2017-09-01
    • 2016-09-25
    • 2017-08-06
    • 1970-01-01
    相关资源
    最近更新 更多