调用 ExpressJS REST 路由时的奇怪行为
Odd behavior while calling ExpressJS REST route
我正在制作一个简单的 REST 服务器,它环绕着 TMDb. And I'm using MovieDB 节点模块的 APIs,它具有直接调用 TMDb 的 APIs 的功能,只需提供 API键。
我有以下应用程序文件夹结构。
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 root 作为 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
应该通过 moviedb
的 genreList()
方法用 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 调用直接被 t运行 指定为 TMDb API 调用(可能是由于相同的 REST 签名)并且 MovieDB 根本没有被调用,我不是不过 100% 确定。
因此,为了确定 MovieDB 模块本身是否有问题,我创建了直接使用 MovieDB 的简单 JS 文件,并使用 node
命令 运行 它,它对所有我正在使用的方法。
那么我在这里做错了什么?
感谢任何帮助。
我找到了问题所在,这是一个愚蠢的问题。
在我的电影路线中,我有一个终点如下。
router.get('/:movieId', function(req, res) {
// Call tmdb.movieInfo()
});
其余端点也以/
开头,如下。
router.get('/popular', function(req, res) {
// Call tmdb.movieInfo()
});
很明显,这是一个糟糕的设计,会引起麻烦,因为 /:movieId
将在传递有效的电影 ID 时调用,但我还有其他使用关键字的要点(与 TMDb 完全相同) ,所以当我在 /popular
上尝试 GET 时,MovieDB 内部调用了 API,由 TMDb 确定(/api/movie/popular
也是 TMDb 的有效端点),因此我得到了正确的结果。
但是,如果我在 /genres
上执行 GET,我的 API 将单词 genres
视为 /:movieId
,因为签名相同,并且没有这样的 ID存在,失败。
我现在已将我的终点更正为
router.get('/info/:movieId', function(req, res) {
// Call tmdb.movieInfo()
});
一切都按预期进行。
经验教训,在涉及参数值和关键字的地方永远不会有相同的端点。
我正在制作一个简单的 REST 服务器,它环绕着 TMDb. And I'm using MovieDB 节点模块的 APIs,它具有直接调用 TMDb 的 APIs 的功能,只需提供 API键。
我有以下应用程序文件夹结构。
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 root 作为 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
应该通过 moviedb
的 genreList()
方法用 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 调用直接被 t运行 指定为 TMDb API 调用(可能是由于相同的 REST 签名)并且 MovieDB 根本没有被调用,我不是不过 100% 确定。
因此,为了确定 MovieDB 模块本身是否有问题,我创建了直接使用 MovieDB 的简单 JS 文件,并使用 node
命令 运行 它,它对所有我正在使用的方法。
那么我在这里做错了什么?
感谢任何帮助。
我找到了问题所在,这是一个愚蠢的问题。
在我的电影路线中,我有一个终点如下。
router.get('/:movieId', function(req, res) {
// Call tmdb.movieInfo()
});
其余端点也以/
开头,如下。
router.get('/popular', function(req, res) {
// Call tmdb.movieInfo()
});
很明显,这是一个糟糕的设计,会引起麻烦,因为 /:movieId
将在传递有效的电影 ID 时调用,但我还有其他使用关键字的要点(与 TMDb 完全相同) ,所以当我在 /popular
上尝试 GET 时,MovieDB 内部调用了 API,由 TMDb 确定(/api/movie/popular
也是 TMDb 的有效端点),因此我得到了正确的结果。
但是,如果我在 /genres
上执行 GET,我的 API 将单词 genres
视为 /:movieId
,因为签名相同,并且没有这样的 ID存在,失败。
我现在已将我的终点更正为
router.get('/info/:movieId', function(req, res) {
// Call tmdb.movieInfo()
});
一切都按预期进行。
经验教训,在涉及参数值和关键字的地方永远不会有相同的端点。