Routes are not working in my express js app - node.js

I was working on a personal express project. I've created two files one server file and other restaurants.route.js to sepearate routes and server code. But I'm not able trigger the home route from local host. Moreover no console error is showing only the 404 page error.
server.js code:
import express from "express";
import cors from "cors";
import restaurants from "./api/restaurants.route.js";
// initialising express app
const app = express();
// applying middlewears
app.use(cors());
app.use(express.json());
app.use("api/v1/restaurants", restaurants);
app.use("*", (req, res) => res.status(404).json({error: "not found"}));
export default app;
restaurants.route.js:
import express from "express";
// express router
const router = express.Router();
router.route("/")
.get((req, res) => {
res.send("Hello World");
});`enter code here`
export default router;

It looks like you might be missing the leading forward slash (/) in the path you're using to mount the restaurants router in your server.js file. When you use the app.use() method to mount a router, the path you specify should start with a forward slash.
So instead of this:
app.use("api/v1/restaurants", restaurants);
Try this:
app.use("/api/v1/restaurants", restaurants);

Related

My express router not working on my express app

I am learning express js.
Here I am creating a crud project in student data. I have created routes and controllers but when I include it in my main app.js , my router seems not working.
Please guide me.
P.S:I am working on ES6.
My app.js
import express from 'express';
import connectDB from './db/connectdb.js'
import web from "./routes/web.js"
import{join} from 'path'
const app = express();
const port = process.env.PORT || "8080"
const DATABASE_URL ="mongodb://127.0.0.1:27017"
//loading static files
app.use('/student',express.static(join(process.cwd(),"public")))
//loading routes
app.get('/student',web)
//set template engine
app.set("view engine","ejs")
app.listen(port,()=>{
console.log("Server listening at port no:"+port)
})
connectDB(DATABASE_URL)
My router file saved as web.js
import express from 'express';
import StudentController from "../controllers/studentController.js"
const router = express.Router();
router.route('/',StudentController.getAllDoc)
export default router
My studentController.js
class StudentController{
static getAllDoc = (req,res)=>{
res.render('index')
}
}
export default StudentController
I expected my ejs file named as index.ejs to run which is in views folder, but the result is like cannot get /student/
.use is used to register middleware, serve group of route,...
.get, .post is a single route.
Please change your code to something like this:
app.js
//loading static files
app.use(express.static(join(process.cwd(),"public")))
//loading routes
app.use('/student',web)
web.js
const router = express.Router();
router.get('/',StudentController.getAllDoc)
export default router

Use Auth0 API protected route with Express route handlers

I implemented protected API routes in Express using the Auth0 quick start. Protected routes are handled with a middleware function called checkJwt, provided by Auth0. It runs whenever one of the GET methods is called. This process works well if I manage all my routes in server.js.
How can I separate out the route handling and still preserve the protected API routes?
server.js working code with protected routes.
import colors from 'colors'
import cors from 'cors'
import express from 'express'
import morgan from 'morgan'
import dotenv from 'dotenv'
import connectDB from './db.js'
import checkJwt from './middleware/auth.middleware.js'
import { getStudents, getStudent } from './controllers/students.controller.js'
dotenv.config()
connectDB()
export const app = express()
app.use(cors())
app.use(express.json({ limit: '50mb' }))
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'))
}
//handle routing internally
app.get('/api/students/:id', checkJwt, getStudent)
app.get('/api/students', checkJwt, getStudents)
const PORT = process.env.PORT || 6000
app.listen(PORT, () =>
console.log(
`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`.yellow.bold
)
)
I want to divorce out the route handling as my code grows. I can't figure out where to put checkJwt once I separate out the routing.
server.js desired code structure is:
import colors from 'colors'
import cors from 'cors'
import express from 'express'
import morgan from 'morgan'
import dotenv from 'dotenv'
import connectDB from './db.js'
import studentsRouter from './routes/students.routes.js'
dotenv.config()
connectDB()
const app = express()
app.use(cors())
app.use(express.json({ limit: '50mb' }))
if (process.env.NODE_ENV === 'development') {
app.use(morgan('dev'))
}
// handle routing externally
const apiRouter = express.Router()
app.use('/api', apiRouter)
apiRouter.use('/students', studentsRouter)
const PORT = process.env.PORT || 6000
app.listen(PORT, () =>
console.log(
`Server running in ${process.env.NODE_ENV} mode on port ${PORT}`.yellow.bold
)
)
Routes are implemented in the students.routes.js Route handler.
import express from 'express'
import { getStudent, getStudents } from '../controllers/students.controller.js'
const router = express.Router()
// where can I implement checkJwt?
router.route('/').get(getStudents)
router.route('/:id').get(getStudent)
export default router
Is it possible to simplify the code by moving the routing, and still protect my routes?
you can use any middleware like this in your router:
const router = express.Router();
router.route('/').get([checkJwt, secondMiddleware, ...] , getStudents);
based on documentation:
express-routing
You can provide multiple callback functions that behave like middleware to handle a request. The only exception is that these callbacks might invoke next('route') to bypass the remaining route callbacks. You can use this mechanism to impose pre-conditions on a route, then pass control to subsequent routes if there’s no reason to proceed with the current route.

Confusion with app.use with Router() in express

I was learning Express in Node.js and came across Router() allowing us to modularize our routes. But than I found this code:
// we'll create our routes here
// get an instance of router
var router = express.Router();
...
// route with parameters (http://localhost:8080/hello/:name)
router.get('/hello/:name', function(req, res) {
res.send('hello ' + req.params.name + '!');
});
// apply the routes to our application
app.use('/', router);
What confused me is that why we need to use app.use('/', router); to apply the routes. That is, what if we use app.get('/', router);
I am giving you a simple code example to make you understand the use of express.Router(). Yes you are right that it helps in modularization. Actually it makes our main app.js file clean from all the routes. We just put all those routes based on their purposes in different files and require them when needed.
so suppose I have two files app.js and register.js
// app.js file's code goes here
let express = require("express")
let app = express()
let register = require("./routes/register")
app.use(register) // This will tell your app to import all those routes which are in register
// register.js file's code goes here
let express = require("express")
let router = express.Router()
router.get("/register", callback_function);
router.post("/register", callback_function);
module.exports = router;
So basically what I am trying to show is your register.js can contain all types of HTTP requests(GET, POST, PUT,...) and when we use app.use(register) this will handle all those routes. app.get("route_path", callback_function) is only for handling get requests to that path.
Router is just a middleware of it's own. If you use app.get('/', router) you will use the router just for GET requests. Using use channels all requests there.
When app.use is used then it handled all the HTTP methods, but when app.get is used it takes just GET method.
Added advantage to app.use is that route will match any path that follows its path immediately with a /.
For example:
app.use('/v1', ...)
will match /users, /users/accounts, /users/accounts/account-id, and so on.

NodeJS Express routes in external file 404 Not Found

I'm new to NodeJs and express. My goal is to have a separate route file that contains all my application routes. So I created a file called routes.js. The content looks like this:
const express = require('express');
const router = express.Router();
router.get('auth/register', require('./controllers/auth/register'));
module.exports = router;
In my main file, I require the file with this line. The app variable contains my express instance.
app.use('/', require('./routes'));
If I call http://localhost/auth/register in my browser, I'm always running into a 404 Not Found error. When I define the route directly in the main file with app.get('/auth/register', require('./controllers/auth/register')); it works well. There are no errors in my console.
Has anyone an idea why my sperate route file does not work? Thank you for your help!
Traditionally, I do the following which is to pass the express instance into your routes module:
once I have instantiated my express instance called app
app.js
require('./routes.js')(app);
routes.js where registerUser us the function to call when the route is matched
module.exports = (app) => {
app.route('/auth/register')
.post(registerUser);
}
You want to pass app into your routes file. A good pattern for this is to import your routes in your main file, like const routes = require('./routes');
In routes, you can define all of your routes like so:
module.exports = (app, router) => {
router.route("/").get()
router.route("/something_else").post()
app.use("/api", router)
...
};
This way, in your main file, you can do: routes(app, router) and have access to app and router inside your routes.js.

Where is the domain mapped to app routers?

const express = require('express');
const router = express.Router();
router.get('/specialRoute', function (req, res, next) {
// route is now http://domain:3000/route/specialRoute
});
router.get('/', function (req, res, next) {
// route is now http://domain:3000
});
module.exports = router;
However, where is the 'domain' mapped to '/' ? In other words, where is the logic to route 'http://domain:3000' -> router.get('/',
An express.Router is not an express application (which is what is used for said binding).
Usually the mapping defaults to localhost because you assign a domain name to an IP and the DNS does the wiring.
If you look at Express's listen documentation on devdocs you'd see that you can pass a host as a second parameter : app.listen(80, "mywebsite");
If you want to map a router to the root ("the domain") you first need an express application:
const app = express();
Then, use the router:
app.use(router);
To make it even neater: Express apps themselves are instances of Router so if you replace router.get with app.get it will be functionally the same.
The reason you would want to create a new Router and export it would be to have multiple router modules and then require them from a main file like this:
const express = require("express");
const app = express();
app.use("/shop", require("./path-to-your-shop-router.js"));
Also, don't forget to make the server listen so you can visit it on your computer:
// Ports <1024 are usually restricted
app.listen(3000);

Resources