Hasan Sefa Ozalp
Hasan Sefa Ozalp

Reputation: 7208

Express - can't import routes

I have a following structure,

// app.js
const express = require("express");
const app = express();

app.get("/", require("./routes/index"));
app.get("/users", require("./routes/users"));

app.listen(3000);

// /routes/index.js
const express = require("express");
const router = express.Router();

router.get("/", (req, res) => res.send("index"));

module.exports = router;

// /routes/users.js
const express = require("express");
const router = express.Router();

router.get("/login", (req, res) => res.send("login"));
router.get("/register", (req, res) => res.send("register"));

module.exports = router;

If I use app.use(...) inside app.js then the routes work correctly but I want to use app.get since I want to block any other accessible method.

Right now the index route works fine but other routes does not work.

Working sandbox: https://codesandbox.io/s/cocky-cartwright-h82d2?fontsize=14&hidenavigation=1&theme=dark

Upvotes: 0

Views: 1197

Answers (2)

GersonLCSJunior
GersonLCSJunior

Reputation: 383

The correct way to achieve what you're trying is to utilize the 'use' function.

You said you don't want to use the app.use because you want to block any other accessible method, but utilizing the 'use' function won't allow anything that wasn't declared on your routers, so you don't need to worry about that.

What app.use does is register a middleware function to your app on the specified route. So, the code below:

app.use("/users", require("./routes/users"));

Will make that every request that match the pattern '/users' will utilize the function you provided (in this case, the router inside the users.js file).

So, if someone sends a POST request to /users/register, per example, he will get a 404, because you never created a route to handle a post on that path.

And just to make it clear why the app.get don't work the way you did, let me give a brief explanation.

When you use the app.get function, it'll be expected that the request path matches exactly the one you provided. So, when you do the following:

app.get("/users", require("./routes/users"));

The server will be expecting a request that matches /users exactly. So, something like /users/example will not trigger the callback function.

The thing is, the function to handle the request in the code above is another router:

router.get("/login", (req, res) => res.send("login"));
router.get("/register", (req, res) => res.send("register"));

So, the router will expect that the request path matches /users/login or /users/register exactly. But, if a request path matches /users/register, it will not match /users, so nothing will be called.

The reason why your '/' path works right now is because your router is expecting the same path you used on the app.js file. So, a request to '/' will match both patterns.

Upvotes: 1

Abanoub Istfanous
Abanoub Istfanous

Reputation: 966

you can't use router.get and pass a router router.get expect to get a method (function). you should use app.use or use controllers like that

// /controllers/index.js
exports.renderIndex = (req, res) => {

    res.send("index")

}


and in app.js

// app.js
const express = require("express");
const app = express();
const indexController = require("./controllers/index");

app.get("/", indexController.renderIndex);

app.listen(3000);

Upvotes: 0

Related Questions