node.jsmongodbexpressmongoose

Cannot GET /api->when i get data from mogodb database by mogoose and show it on the page with api


in windows 10 , i'm using vscode 1.88.0 , node v20.3.1 , express 4.21.0 , dotenv 16.4.5 , mongoose 8.6.4 , express-mongo-sanitize 2.2.0.

Note : I get this error when I try to display the mongoDb data as an array on the page when I connect to it through mongoose via api, but I get this error -> Cannot GET /api.

Consider - models/middleBannerModel.js:

const mongoose = require("mongoose");
const MiddleBanner = new mongoose.Schema({
  image: {
    required: true,
    type: String,
    default: 0,
  },
  imageAlt: {
    required: true,
    type: String,
  },
  situation: {
    required: true,
    type: Boolean,
  },
  link: {
    required: true,
    type: String,
  },

  date: {
    type: String,

    default: new Date().toLocaleDateString("fa-IR", {
      hour: "2-digit",
      minute: "2-digit",
    }),
  },
});
module.exports = mongoose.model("MiddleBanner", MiddleBanner);

Consider - controllers/middleBannerController.js:

const MiddleBanner = require("../models/middleBannerModel");

const getAllMiddleBanners = async (req, res) => {
  try {
    const AllMiddleBanners = await MiddleBanner.find();
    res.status(200).json(AllMiddleBanners);
  } catch (err) {
    console.log(err);
    res.status(400).json({ msg: "error" });
  }
};

module.exports.getAllMiddleBanners = getAllMiddleBanners;

Consider - routes/middleBannerRoute.js:

const express = require("express");
const router = express();
const MiddleBannerController = require("../controllers/middleBannerController");

router.get("/middle-banners", MiddleBannerController.getAllMiddleBanners);

module.exports = router;

Consider - .env file:

PORT=9000
DB_URL=mongodb+srv://***************************************************************************

Consider - server.js:

// var fs = require("fs");
// var http = require("http");
// var https = require("https");
// var privateKey = fs.readFileSync("./sslcert/server.key", "utf8");
// var certificate = fs.readFileSync("./sslcert/server.crt", "utf8");
// var credentials = { key: privateKey, cert: certificate };
const express = require("express");
const app = express();
const bodyParser = require("body-parser");
const cookieParser = require("cookie-parser");
const mongoose = require("mongoose");
const cors = require("cors");
require("dotenv/config");

// security packages
const helmet = require("helmet");
const xssCleaner = require("xss-clean");
const mongoSanitize = require("express-mongo-sanitize");
const hpp = require("hpp");

//mid
app.use(bodyParser.json({ limit: "50mb" }));
app.use(
  bodyParser.urlencoded({
    limit: "50mb",
    extended: true,
    parameterLimit: 50000,
  })
);

app.use(cookieParser());
app.use(cors());
app.use(helmet());
app.use(xssCleaner());
app.use(mongoSanitize());
app.use(hpp());
// your express configuration here

// var httpServer = http.createServer(app);
// var httpsServer = https.createServer(credentials, app);
// connect to mongodb
const PORT = process.env.PORT;
const DB_URL = process.env.DB_URL;
app.get("/", (req, res) => {
  res.status(200).json({
    msg: "this is mernfa file shop course server ...",
  });
});
// ROUTES
const middleBannerRoutes = require("./routes/middleBannerRoute");

// ROUTES MIDDLEWARE

app.use("/api", middleBannerRoutes);

mongoose
  .connect(DB_URL)
  .then((d) => {
    app.listen(PORT);
    console.log("Connected to database");
  })
  .catch((err) => console.log(err));

Note : I guess I connect to the database and I don't have any errors but when I show the database data as an array by api and make a GET request on the page I get this error -> Cannot GET /api.

My folder structure : enter image description here

please help me to solve it !


Solution

  • The problem is with middleBannerRoute router: you don't have a handler for /api route, but for /api/middle-banners, so the error is expected.

    So, either change your request to /api/middle-banners, or change router's path to /:

    // remove `/middle-banners`, so that now it will handle `/api`
    
    router.get("/", MiddleBannerController.getAllMiddleBanners);
    

    It would probably be better to do both, so that you can mount different controllers on /api path, and make it more readable, for example:

    // server
    app.use("/api/middle-banners", middleBannerRoutes);
    
    // router
    router.get("/", MiddleBannerController.getAllMiddleBanners);
    // ..other methods and more specific paths..
    //router.post("/", MiddleBannerController.postHandler);
    // etc.
    
    
    // ..later..
    // server
    app.use("/api/something-else-now", otherStuffRoutes);
    

    see: express.Router