Search code examples
node.jsexpresspostmanprisma

How to return error status in node.js and expess when the user use wrong http method on a route?


I'm new to node.js and I'm trying to make an API, so I would like to know how to detect when the user use wrong http method on a route. Example of what I'm trying to do. On the above picture, the user should use a GET but instead used a PUT, so the API return an error message and status code.

Here is my router file:

const router = require('express').Router();
const controller = require('../controllers/users.controller')

router.get('/', controller.getAll);
router.get('/actives', controller.getAllActive);
router.get('/:id', controller.getById);
router.post('/register', controller.create);
router.post('/auth', controller.authenticate);
router.put('/:id', controller.update);
router.put('/:id/activate', controller.activate);
router.put('/:id/deactivate', controller.deactivate);

module.exports = router

My server file:

const express = require('express');
const cors = require('cors');
require('dotenv').config();
const server = express();
const port = process.env.PORT;
server.use(cors());
server.use(express.urlencoded({ extended: false }))
server.use(express.json());

const usersRouter = require('./routes/users.router');
server.use('/api/v1/users', usersRouter);

server.listen(port, (err) => {
  if (err) {
    console.log("error while starting server");
  } else {
    console.log(`Server running at http://localhost:${port}/`);
  }
});

And my getAllActive method in controller (I'm using Prima as ORM)

getAllActive: async (req, res) => {
    try {
      const allActiveUsers = await prisma.user.findMany({ where: { active: true } });
      res.json({ message: "Done", data: allActiveUsers });
    } catch (error) {
      console.log(error);
      res.status(500).json({ message: "Error" });
    }
  },

I tried to do this in server file:

const methodOverride = require('method-override');
server.use(methodOverride('_method'));
server.use((req, res, next) => { res.status(405).json({ message: req.method + ' method not allowed on ' + req.originalUrl + ' route.' }); });

but if I put in before

const usersRouter = require('./routes/users.router');
server.use('/api/v1/users', usersRouter);

it would reject all http methods, and if I put it after, it won't do anything.

I'm using Node.js v19.3.0.


Solution

  • With the help of the comments I solved my problem like this in my router file:

    const router = require('express').Router();
    const controller = require('../controllers/users.controller')
    const methodNotAllowed = (req, res) => res.status(405).json({ message: `${req.method} method not allowed on ${req.originalUrl} route.` });
    
    router.route('/').get(controller.getAll).all(methodNotAllowed);
    router.route('/actives').get(controller.getAllActive).all(methodNotAllowed);
    router.route('/register').post(controller.create).all(methodNotAllowed);
    router.route('/auth').post(controller.authenticate).all(methodNotAllowed);
    router.route('/:id').get(controller.getById).put(controller.update).all(methodNotAllowed);
    router.route('/:id/activate').put(controller.activate).all(methodNotAllowed);
    router.route('/:id/deactivate').put(controller.deactivate).all(methodNotAllowed);
    

    UPDATE

    Again with the help of comments, I found out an easier way than the previous. Here it is:

    router.route('/').get(controller.getAll)
    router.route('/actives').get(controller.getAllActive)
    router.route('/register').post(controller.create)
    router.route('/auth').post(controller.authenticate)
    router.route('/:id').get(controller.getById)
    router.route('/:id/activate').put(controller.activate)
    router.route('/:id/deactivate').put(controller.deactivate)
    // add this line add the end and remove ".all(methodNotAllowed)" on the other lines
    router.route('/*').all(methodNotAllowed)