调用ExpressJS REST路由时的奇怪行为

时间:2016-06-15 12:00:30

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

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

我有以下app文件夹结构。

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

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

的myproject / 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 /路由/ index.js

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

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

的myproject /路由/电影/ 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应该通过moviedb的{​​{1}}方法回复TMDb API提供的类型列表,以防我理解路由和路由图是正确的。

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

genreList()

如果您看到{ "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,这显然是不正确的,因为TMDb API没有任何此类终点。

但是,如果我将https://api.themoviedb.org/3/movie/genrelist内的router.get更改为以下内容:

myproject/routes/movie/index.js

一切正常,请注意我也将来自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()部电影的列表。

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

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

那我在这里做错了什么?

感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

我发现了问题所在,这是一个愚蠢的问题。

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

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

剩余的终点也以/开头,如下所示。

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

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

但是,如果我在/genres上执行GET,我的API会将genres一词视为/:movieId,因为签名相同,并且由于不存在此类ID,因此失败。< / p>

我现在更正了我的终点

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

一切都按预期工作。

经验教训,从来没有相同的终点,其中涉及参数值和关键字。