ppalmeida ppalmeida - 1 year ago 58
Node.js Question

expressjs route: specific route is not recognized


I am doing just a very simple API (localhost development), and I am curious why the last route is never got by ExpressJS server.

Here are the routes:

var express = require('express');
var bodyParser = require('body-parser');
var router = express();

// (...) other variables defined here...

router.all('*', function(req, res, next) {
res.header('Access-Control-Allow-Origin', 'localhost');
res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');

// Works great!
router.get('/', function(req, res) {

// Works great!
router.get('/api/states', function(req, res) {

// Works great!
router.get('/api/cities/:state', function(req, res, state) {

// Never Works!!
router.get('/api/stores/:state/:city', function(req, res, state, city) {
res.json('{"result": true}');

router.use(express.static(__dirname + '/../../www'));
router.set('views', __dirname + '/../../www');
router.engine('html', require('ejs').renderFile);
router.set('view engine', 'html');
router.listen(process.env.PORT || 9000);

From my app I call these URLs to the last route:


It is always 404.

I simply can not realise why this is 404. The last route, witch never worked, is basically a copy from the previous route (that works great).

Could someone point what I am doing wrong here?

ps: the last route should accept a third optional parameter. I also had tried this:

// Never Works!!
router.get('/api/stores/:state/:city/*?', function(req, res, state, city) {
res.json('{"result": true}');

But, if I can not do it work with two defined parameters, it will not work with extra optional parameters, right?

Any advice is very appreciate.

Thank you.

Answer Source

You have too many arguments in your handler--function handlers that take four arguments are reserved for error handling, i.e. only called when somewhere in the middleware chain next(error) was called, or a exception was caught. Read the docs for further info.

// Remove `state` and `city` arguments, access via `req.params.*`
router.get('/api/stores/:state/:city', function(req, res) {
  var state = req.params.state
  var city = req.params.city
  res.json('{"result": true}');

The reason you are not getting a 404 for the other handler is because you're accepting three arguments. So I should point out the state argument will not be what you expect, it will be a function to invoke the next middleware, commonly named next.

// NOPE! function (req, res, state)
router.get('/api/cities/:state', function(req, res) { 
   var state = req.params.state

// Common middleware handler, third parameter is a function that when invoked will call the next middleware
router.get('/some/uri', function (req, res, next) {
     .then(data => { 
        req.data = data 
      .catch(err => next(err))
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download