Red Cricket
Red Cricket

Reputation: 10470

Having trouble understand express.js

I am trying to learn about MEAN stack and I have followed this tutorial:

https://www.airpair.com/node.js/posts/getting-started-with-docker-for-the-nodejs-dev

The tutorial is pretty good but also basic when it comes to express.js. One ends up with a REST API that responds with, <!DOCTYPE html><html><head><title>Express</title><link rel="stylesheet" href="/stylesheets/style.css"></head><body><h1>Express</h1><p>Welcome to Express</p></body></html> if I execute curl -X GET http://172.17.0.11:3000. Also, if I execute: curl -X GET http://172.17.0.11:3000/users the API responses with respond with a resource. All this was created in the tutorial when I executed: express mynodeapp. I wanted to make the REST API respond to this request:

curl -H Content-Type: application/json -X POST -d '{username:xyz,password:xyz}' http://172.17.0.11:3000/user/add

So I poked around the mynodeapp directory and modified my app.js file http://pastebin.com/52TA5VZ6 . I added the stuff between the //RED comments. I also added a file in the routes directory:

[root@f271de68b259 routes]# cat user.js
var express = require('express');
var router = express.Router();

/* add user */
router.post('/user/add', function (req, res) {
  res.send('respond with a resource see http://expressjs.com/api.html#app.post.method');
});

module.exports = router;

But the response I get is:

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
<!DOCTYPE html><html><head><title></title><link rel="stylesheet" href="/stylesheets/style.css"></head><body><h1>Not Found</h1><h2>404</h2><pre>Error: Not Found
    at app.use.res.render.message (/mynodeapp/app.js:38:13)
    at Layer.handle [as handle_request] (/mynodeapp/node_modules/express/lib/router/layer.js:95:5)
    at trim_prefix (/mynodeapp/node_modules/express/lib/router/index.js:312:13)
    at /mynodeapp/node_modules/express/lib/router/index.js:280:7
    at Function.process_params (/mynodeapp/node_modules/express/lib/router/index.js:330:12)
    at next (/mynodeapp/node_modules/express/lib/router/index.js:271:10)
    at /mynodeapp/node_modules/express/lib/router/index.js:618:15
    at next (/mynodeapp/node_modules/express/lib/router/index.js:256:14)
    at Function.handle (/mynodeapp/node_modules/express/lib/router/index.js:176:3)
    at router (/mynodeapp/node_modules/express/lib/router/index.js:46:12)</pre></body></html>

I am kind of lost on what I am doing wrong. Can anyone out there help me out? Thanks!

UPDATE: Thanks for all your responses. I have changed my routes/user.js to this as per your suggestions:

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

/* add user */
router.post('/add', function (req, res) {
  res.send('respond with a resource see http://expressjs.com/api.html#app.post.method');
});

module.exports = router;

Now I do get the response one would expect, but I am also getting a 301 message. Here is what curl -H Content-Type: application/json -X POST -d '{username:xyz,password:xyz}' http://172.17.0.11:3000/user/add is outputting now:

<html>
<head><title>301 Moved Permanently</title></head>
<body bgcolor="white">
<center><h1>301 Moved Permanently</h1></center>
<hr><center>nginx</center>
</body>
</html>
respond with a resource see http://expressjs.com/api.html#app.post.method

Is that to be expected? I am doing something else wrong now?

Thanks!

Upvotes: 0

Views: 334

Answers (3)

FelisCatus
FelisCatus

Reputation: 5334

Please check your app.js generated by the express-generator. Around Line 26 it should contain something like this:

app.use('/users', users);

Which means, in your user.js file, the router is always used with the /users prefix. So you should omit the /users part when defining routes:

router.post('/add', function (req, res) {
  res.send('respond with a resource see http://expressjs.com/api.html#app.post.method');
});

Please note this makes your API available at POST /users/add, which contains an extra s after user. If you want to change this, you can always edit the app.js and mount the user router at /user:

app.use('/user', users);

Please check the Express Router docs to see how to define routes under a router, and how to mount them under a URL prefix.

Upvotes: 1

nkl
nkl

Reputation: 598

So in your app.js, you've defined your user route as this:

app.use('/user', user);

Then in your actual route file (user.js), you've defined the post request handler as this:

router.post('/user/add'

What this means, is that in order to get to this post request, you would need to send the request to: '/user/user/add'.

If this is not what you want, change:

router.post('/user/add'

to simply:

router.post('/add'

Upvotes: 1

winter
winter

Reputation: 182

You don't need to add /user/ to your router in the code below

/* add user */
router.post('/user/add', function (req, res) {
  res.send('respond with a resource see http://expressjs.com/api.html#app.post.method');
});

Because you have specified it in app.use('/user', user);

Just change it to

/* add user */
router.post('/add', function (req, res) {
  res.send('respond with a resource see http://expressjs.com/api.html#app.post.method');
});

Upvotes: 2

Related Questions