I’m working through a YouTube tutorial. The code is exactly the same as that in the tutorial, but for some reason, .get, .put, and .delete in the api/reviews.route.js (below) isn’t working. It uses a path that’s not recognized, resulting in the error message. I can’t figure out why this is happening. I’m able to do a new POST for a new review and also GET works with /movie/id.
Curl cmd that fails: ~/BackendTutorial$ curl -X GET https://5f792143-0815-429e-9959-760bcffffff4-00-318ewmjhtmkqx.spock.repl.co/api/v1/reviews/65c3f5d3e3353aaccca550c1
{“error”:{}}~/BackendTutorial$
CODE BELOW:
api folder containing reviews.route.js
import express from "express";
import ReviewsCtrl from "./reviews.controller.js";
const router = express.Router();
router.route("/movie/:id").get(ReviewsCtrl.apiGetReviews);
router.route("/new").post(ReviewsCtrl.apiPostReview);
router
.route("/:id")
.get(ReviewsCtrl.apiGetReview)
.put(ReviewsCtrl.apiUpdateReview)
.delete(ReviewsCtrl.apiDeleteReview);
export default router;
api folder containing reviews.controller.js
import ReviewsDAO from "../dao/reviewsDAO.js";
export default class ReviewsController {
static async apiPostReview(req, res, next) {
try {
const movieId = parseInt(req.body.movieId);
const review = req.body.review;
const user = req.body.user;
console.log("movieid", movieId);
const reviewResponse = await ReviewsDAO.addReview(movieId, user, review);
res.json({ status: "success" });
} catch (e) {
res.status(500).json({ error: e.message });
}
}
static async apiGetReview(req, res, next) {
try {
let id = req.params.id || {};
let review = await ReviewsDAO.getReview(id);
if (!review) {
res.status(404).json({ error: "Not found" });
return;
}
res.json(review);
} catch (e) {
console.log(`api, ${e}`);
res.status(500).json({ error: e });
}
}
static async apiUpdateReview(req, res, next) {
try {
const reviewId = req.params.id;
const review = req.body.review;
const user = req.body.user;
const reviewResponse = await ReviewsDAO.updateReview(
reviewId,
user,
review,
);
var { error } = reviewResponse;
if (error) {
res.status(400).json({ error });
}
if (reviewResponse.modifiedCount === 0) {
throw new Error("unable to update review");
}
res.json({ status: "success" });
} catch (e) {
res.status(500).json({ error: e.message });
}
}
static async apiDeleteReview(req, res, next) {
try {
const reviewId = req.params.id;
const reviewResponse = await ReviewsDAO.deleteReview(reviewId);
res.json({ status: "success" });
} catch (e) {
res.status(500).json({ error: e.message });
}
}
static async apiGetReviews(req, res, next) {
try {
let id = req.params.id || {};
let reviews = await ReviewsDAO.getReviewsByMovieId(id);
if (!reviews) {
res.status(404).json({ error: "Not found" });
return;
}
res.json(reviews);
} catch (e) {
console.log(`api, ${e}`);
res.status(500).json({ error: e });
}
}
}
dao folder with reviewsDAO.js
import mongodb from "mongodb";
const ObjectId = mongodb.ObjectID;
let reviews;
export default class ReviewsDAO {
static async injectDB(conn) {
if (reviews) {
return;
}
try {
reviews = await conn.db("reviews").collection("reviews");
} catch (e) {
console.error(`Unable to establish collection handles in userDAO: ${e}`);
}
}
static async addReview(movieId, user, review) {
try {
const reviewDoc = {
movieId: movieId,
user: user,
review: review,
};
console.log("adding");
return await reviews.insertOne(reviewDoc);
} catch (e) {
console.error(`Unable to post review: ${e}`);
return { error: e };
}
}
static async getReview(reviewId) {
try {
return await reviews.findOne({ _id: ObjectId(reviewId) });
} catch (e) {
console.error(`Unable to get review: ${e}`);
return { error: e };
}
}
static async updateReview(reviewId, user, review) {
try {
const updateResponse = await reviews.updateOne(
{ _id: ObjectId(reviewId) },
{ $set: { user: user, review: review } },
);
return updateResponse;
} catch (e) {
console.error(`Unable to update review: ${e}`);
return { error: e };
}
}
static async deleteReview(reviewId) {
try {
const deleteResponse = await reviews.deleteOne({
_id: ObjectId(reviewId),
});
return deleteResponse;
} catch (e) {
console.error(`Unable to delete review: ${e}`);
return { error: e };
}
}
static async getReviewsByMovieId(movieId) {
try {
const cursor = await reviews.find({ movieId: parseInt(movieId) });
return cursor.toArray();
} catch (e) {
console.error(`Unable to get review: ${e}`);
return { error: e };
}
}
}
index.js file:
import app from "./server.js";
import mongodb from "mongodb";
import ReviewsDAO from "./dao/reviewsDAO.js";
const MongoClient = mongodb.MongoClient;
const mongo_username = process.env["MONGO_USERNAME"];
const mongo_password = process.env["MONGO_PASSWORD"];
const uri = `mongodb+srv://${mongo_username}:${mongo_password}@cluster0.yowfgs9.mongodb.net/?retryWrites=true&w=majority`;
const port = 8000;
MongoClient.connect(uri, {
maxPoolSize: 50,
wtimeoutMS: 2500,
useNewUrlParser: true,
})
.catch((err) => {
console.error(err.stack);
process.exit(1);
})
.then(async (client) => {
await ReviewsDAO.injectDB(client);
app.listen(port, () => {
console.log(`listening on port ${port}`);
});
});
server.js file:
import express from "express";
import cors from "cors";
import reviews from "./api/reviews.route.js";
const app = express();
app.use(cors());
app.use(express.json());
app.use("/api/v1/reviews", reviews);
app.use("*", (req, res) => res.status(404).json({ error: "not found" }));
export default app;
package.json file:
{
"name": "nodejs",
"version": "1.0.0",
"description": "",
"main": "index.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@types/node": "^18.0.6",
"cors": "^2.8.5",
"express": "^4.18.2",
"mongodb": "^6.3.0",
"node-fetch": "^3.2.6"
}
}