Home > Software design >  why GET method does not work while POST works for same api calll in express?
why GET method does not work while POST works for same api calll in express?

Time:08-27

I got confused while running my code. I am trying to make an API route for searching books and when I apply POST method it works and does what I want to achieve while there is nothing in body but when I apply GET method it shows following error:

CastError: Cast to ObjectId failed for value "search" (type string) at path "_id" for model "bookmodel"
    at model.Query.exec (E:\FullStacks\BookStore\node_modules\mongoose\lib\query.js:4803:21)
    at model.Query.Query.then (E:\FullStacks\BookStore\node_modules\mongoose\lib\query.js:4902:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  messageFormat: undefined,
  stringValue: '"search"',
  kind: 'ObjectId',
  value: 'search',
  path: '_id',
  reason: BSONTypeError: Argument passed in must be a string of 12 bytes or a string of 24 hex characters or an integer

what could be the reason behind it? route:

router.get("/search", bookcontoller.searchBook)
async searchBook(req, res) {
    try {
      const { query } = req.query;
      console.log(query);
      if (!query) {
        return res.status(400).json({ success: false, msg: "query not found" });
      }

      const searchResult = await bookModel.find({$or:[{name:{$regex:".*" query ".*"}}, {genre:{$regex:".*" query ".*"}}]})
      if(searchResult.length == 0){
        return res.json({success:false, msg:"nothing found of that query"})
      }
      return res.status(200).json({success:true, msg:"search has been successful", searchResult})

    } catch (error) {
      return res.status(400).json(error);
    }
  }

url:

localhost:8000/book/search?query=hi

CodePudding user response:

You very likely also have a route looking like this:

router.get('/:id', ...)

And the handler of that route uses req.params.id to perform a query on bookModel to find the book with that id.

Then, you declared the route you're showing:

router.get('/search', …)

Express does not pick the best route handler that matches, but the first. And a request for /search will match the route for /:id just fine. So you're performing a query against bookModel using the word "search" (now in req.params.id) as _id, which fails because that's not a valid ObjectId.

The solution is to always declare more specific route handlers first:

router.get('/search', …)
router.get('/:id', …)
  • Related