Странное поведение при вызове ExpressJS REST-маршрута

Я делаю простой REST-сервер, который оборачивается вокруг API-интерфейсов TMDb. И я использую модуль MovieDB Node, который имеет функции для прямого вызова API TMDb, предоставляя только ключ 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 как 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 должен ответить мне списком жанров, которые предоставляет TMDb API, через moviedb"s 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Звонил https://api.themoviedb.org/3/movie/genrelist что, очевидно, неверно, так как TMDb API не имеет такой конечной точки.

Однако, если я поменяю 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() как есть, так и извлекает список top_rated фильмы.

Даже страшно то, что я делаю console.log() в методе GET и ничего не регистрируется. Даже отладка сервера с помощью node-debug не прерывает выполнение, если я устанавливаю точку останова в GET. Поэтому я чувствую, что мои вызовы REST через REST-клиент напрямую преобразуются в вызовы API TMDb (возможно, из-за идентичных сигнатур REST), а MovieDB вообще не вызывается, хотя я не уверен на 100%.

Итак, чтобы определить, что-то не так с самим модулем MovieDB, я создал простой файл JS, который напрямую использует MovieDB, и запустил его с node команда, и она работала нормально для всех методов, которые я использую.

Так что плохого в том, что я здесь делаю?

Любая помощь приветствуется.

1 ответ

Решение

Я нашел, в чем проблема, и это было глупо.

В моих маршрутах Кино у меня была одна конечная точка следующим образом.

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

И остальные конечные точки также начались с /, следующее.

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

Ясно, что это плохой дизайн и вызовет проблемы, так как /:movieId будет вызван, когда передан действительный идентификатор фильма, но у меня также есть другие пункты, которые используют ключевые слова (точно такие же, как и TMDb), поэтому, когда я попробовал GET на /popular, MovieDB внутренне вызывает API, как определено TMDb (/api/movie/popular является допустимой конечной точкой для TMDb), и, следовательно, я получил результаты правильно.

Однако, если я сделаю GET на /genresмой API подумал о слове genres как /:movieId, из-за идентичной подписи, и, поскольку такого идентификатора не существует, произошел сбой.

Теперь я исправил свою конечную точку как

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

И все работает как положено.

Извлеченный урок, никогда не имейте одинаковых конечных точек, где используются значения параметров и ключевые слова.

Другие вопросы по тегам