Trying to do dynamic route "homework" from next.js and mongoDb tutorial

I’m trying to accomplish the “homework” from the How to intergrate MongoDb with your next.js app tutorial.

“As a homework exercise, why don’t you create an API route that returns a single movie based on a user provided id?”

I have a my file in set up like so : pages/api/[movieId].js

It looks like this :

import clientPromise from "../../lib/mongodb";

export default async (req, res) => {
   try {
       const client = await clientPromise;
      const db = client.db("sample_mflix");
       const id = `${req.query.movieId}`;

       const movie = await db
           .collection("movies")
           .findOne({"_id": ObjectId(id)})
           
           
       res.json(movie);
   } catch (e) {
       console.error(e);
   }
};

I’m getting 404 error in browser at http://localhost:3000/api/movies/573a1394f29313caabcdf67a, and at http://localhost:3000/api/573a1394f29313caabcdf67a, there is something that I am not fully comprehending about dynamic routes yet. What would be the ‘best practice’ way of accomplishing this homework prompt?

You write

So may be you could try

http://localhost:3000/pages/api/573a1394f29313caabcdf67a.js

or

http://localhost:3000/api/573a1394f29313caabcdf67a.js

or

remove .js from

Thanks you for your reply. To clarify a bit, the actual ‘prompt’ from the tutorial is

Blockquote
As a homework exercise, why don’t you create an API route that returns a single movie based on a user provided id? To give you some pointers, you’ll use Next.js Dynamic API Routes to capture the id . So, if a user calls http://localhost:3000/api/movies/573a1394f29313caabcdfa3e , the movie that should be returned is Seven Samurai . Another tip, the _id property for the sample_mflix database in MongoDB is stored as an ObjectID, so you’ll have to convert the string to an ObjectID.

Previously, it has you set up a route in pages/api repository at movies.js, for a long list of movies. Is the ‘.js’ not proper naming convention for routes? I need to set up the movie id as the parameter for the route described in the homework.

According to the Next.js documentation you shared and

I would say that you should set your file as pages/api/movie/[movieId].js and use

http://localhost:3000/api/movie/573a1394f29313caabcdf67a

Okay, I got to be getting closer…as per the tutorial, first we set up a route to get multiple movies. It is set up at pages/api/movies.js and it looks like this

import clientPromise from "../../lib/mongodb";

export default async (req, res) => {
   try {
       const client = await clientPromise;
       const db = client.db("sample_mflix");

       const movies = await db
           .collection("movies")
           .find({})
           .sort({ metacritic: -1 })
           .limit(10)
           .toArray();

       res.json(movies);
   } catch (e) {
       console.error(e);
   }
};

Then, we are asked to set up the dynamic route that is passing the movie id as a param, I have that set up at pages/api/[movieId].js and it now looks like this

import { ObjectId } from "mongodb";
import clientPromise from "../../lib/mongodb";

export default async (req, res) => {
    
   try {    
    const id = req.query.id;
    const client = await clientPromise;
    const db = client.db("sample_mflix");

    const movies = db.collection("movies");
    const movie = await movies.findOne({ _id:ObjectId(id)});
    if(movie){
        res.json(movie);
    }else{
        res.status(404).json({message: "Movies not found"})
    } 
      } catch (e) {
       console.error(e);
       res.status(500).json({ message: "Internal server error" });  
   }
};

I am still getting a 404 error at http://localhost:3000/api/movies/573a1394f29313caabcdf67a,

as well as at http://localhost:3000/api/movie/573a1394f29313caabcdf67a

What am I missing here? I’ve tried multiple movie ids as the param in the browser all of which have returned 404 errors.

Update : when I pass a movie id at api/573a1396f29313caabce3f2c, I get “movie not found”, so the else block in [movieId] is running for sure. I have tried multiple movie ids but get the same error for everyone.

If you setup your route with [movieId] the you should use req.query.movieId as the variable name in your code rather than req.query.id.

If you want to use the variable req.query.id in your code, you have to define your route with [id] rather than [movieId].

@steevej - superlatives, that worked, thank you so much

1 Like