I know there are several version of this but I can't seem to find a solution for mine.
My server doesn't seem to see all routes in my routes file. It only matches the first one.
index.js
import express from 'express'
import mongoose from 'mongoose'
import dotenv from "dotenv";
import tweetRoutes from "./src/routes/tweetRoutes.js";
dotenv.config();
const app = express();
const PORT = process.env.PORT || 5000;
app.use(express.json());
// Routes
app.use("/api/tweets", tweetRoutes);
// DB connection
mongoose.connect(process.env.DB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
});
mongoose.connection.on("connected", () =>
console.log("DB Connection Established!")
);
// Server
app.listen(PORT, () => console.log(`Server listening on: ${PORT}`))
tweetRoutes.js
import { Router } from 'express'
import {
createTweet,
fetchTweets,
fetchTweet,
updateTweet,
deleteTweet,
} from "../controller/tweetController.js";
const router = Router();
router.get("/", fetchTweets);
router.get("/:id", fetchTweet);
router.post("/create-tweet", createTweet);
router.patch("/:id", updateTweet); // Not working
router.delete("/:id", deleteTweet); // Not working
export default router;
In this case, the only route accessible is the first one, fetchTweets. Even when I pass an ID param to get a single tweet using the fetchTweet route, it routes to the first route. The other routes return a 404.
What could I be doing wrong? Any help is highly appreciated.
Thank you for providing the url you used to test the fetchTweet route.
You should use the following path instead to reach the desired route:
127.0.0.1:3000/api/tweets/61b9af93e88ee4de51c28b95
Reference:
https://expressjs.com/en/guide/routing.html
Related
I'm trying to build a demo application and having "Cannot GET /" error when I try to reach out http://localhost:8800/
On the other hand, the output as expected:
Connected to backend.
mongoDB connected!
Connected to mongoDB.
So I couldn't understand where exactly I have the problem, do you have any suggestions?
import mongoose from "mongoose";
import express from "express";
import authRoute from "./routes/auth.js";
import usersRoute from "./routes/users.js";
import hotelsRoute from "./routes/hotels.js";
import roomsRoute from "./routes/rooms.js";
const app = express();
// dotenv.config()
const connect = async ()=>{
try {
await mongoose.connect('mongodb+srv://********#******.mongodb.net/?retryWrites=true&w=majority');
// Check how we can use .env file
console.log("Connected to mongoDB.")
} catch (error) {
throw error
}
};
mongoose.connection.on("disconnected", ()=>{
console.log("mongoDB disconnected!")
})
mongoose.connection.on("connected", ()=>{
console.log("mongoDB connected!")
})
app.use(express.json())
app.use("api/auth", authRoute);
app.use("api/users", usersRoute);
app.use("api/hotels", hotelsRoute);
app.use("api/rooms", roomsRoute);
app.listen(8800, ()=>{
connect()
console.log("Connected to backend.")
});
auth.js
import express from "express";
const router = express.Router();
router.get("/auth", (req,res)=>{
res.send("Hello, this is auth endpoint");
})
router.get("/register", (req,res)=>{
res.send("Hello, this is auth register endpoint");
})
export default router
You don't need a root route. However, if you still want something to display, you can just add in your code :
app.get('/', (_, res) => res.send({message: 'Hello from Express'}))
Your code is running, it just doesn't have a route at '/', which is your path when you go to any website. if you want to render something on the page, just add
app.get('/', (req, res)=>{
res.send('this text will now appear at localhost:8800');
/*
you could also import path and do
path.join(__dirname+'yourfilename.html') to render an html file
*/
})
you can make '/' root
app.get('/', (req, res) => {
res.send('Hello World!')
})
I'm currently setting up a custom Node server with Next.js. The fact that I'm using Next.js shouldn't make any difference though.
In previous apps, I've always used mongoose.connection.once('open', callback) to start listening only when the database is open. This time, it's not working.
This is my connection configuration file:
import mongoose from 'mongoose';
import { MONGO_URI } from '../constants'; // looks like 'mongodb://localhost/my-db' in development
mongoose
.connect(MONGO_URI, () => {
try {
console.log(`Connected to ${MONGO_URI} with Mongoose.`);
} catch (err) {
throw err;
}
})
export default mongoose.connection;
I am importing this and using it in my main.ts file like so:
import express from 'express';
import next from 'next';
import * as dotenv from 'dotenv';
import logger from 'morgan';
import compression from 'compression';
import helmet from 'helmet';
import rateLimiter from './config/rateLimiter';
import db from './config/connection'; // This is the config file
dotenv.config();
const PORT = process.env.PORT || '8000';
const dev = process.env.NODE_ENV !== 'production';
const nxt = next({ dev });
const handle = nxt.getRequestHandler();
nxt.prepare().then(() => {
const app = express();
app.enable('trust proxy');
app.use(logger('dev'));
app.use(helmet());
app.use(rateLimiter);
app.use(compression());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
db.once('open', () => {
app.listen(PORT, () => {
// This log never happens
console.log(`Listening on port ${PORT}.`);
});
});
});
It's extremely strange, because "Connected to mongodb://localhost/my-db with Mongoose." is in fact logged when using the code above, but the express app simply never listens; however, when I remove the app.listen out of the db.once callback function, "Listening on port 8000" does of course get logged.
I'm stumped. Why isn't the 'open' event firing? I've verified that mongo is working locally through the Mongo shell, and this same exact code was working when I had the folder which these files are in (server) separate from the Next.js app (when I was still debating which type of view layer to write).
The issue is not compatibility. I'm running Mongo 5.0.5, and Mongoose 6.2.5, which should be find according to this
Please don't link to some other question. None of these have helped:
My mongo is compatible
mongoose.connect doesn't return a promise
The comment from #Shivam Sood was correct. The db.once('open') was being called too late. Once nxt.prepare had happened, the db was already opened.
Here is the modified code:
import express from 'express';
import next from 'next';
import * as dotenv from 'dotenv';
import logger from 'morgan';
import compression from 'compression';
import helmet from 'helmet';
import rateLimiter from './config/rateLimiter';
import db from './config/connection';
dotenv.config();
const PORT = process.env.PORT || '8000';
const dev = process.env.NODE_ENV !== 'production';
const nxt = next({ dev });
const handle = nxt.getRequestHandler();
db.once('open', () => { // Listen for 'open' event before nxt.prepare, and before listening on PORT
nxt.prepare().then(() => {
const app = express();
app.enable('trust proxy');
app.use(logger('dev'));
app.use(helmet());
app.use(rateLimiter);
app.use(compression());
app.use(express.urlencoded({ extended: false }));
app.use(express.json());
app.get('*', (req, res) => {
return handle(req, res);
});
app.listen(PORT, () => {
console.log(`Listening on port ${PORT}.`);
});
});
});
Here is my App.js file
const express = require("express");
const dotenv = require("dotenv");
const movieRouter = require("./routes/movieRoutes");
const userRouter = require("./routes/userRoutes");
const app = express();
dotenv.config({ path: "./config.env" });
app.use(express.json());
//Mounting routes
app.use("/kramank-api/v1/movies", movieRouter);
app.use("/kramank-api/v1/users", userRouter);
app.use(express.static("./"));
module.exports = app;
Here is my Server.js file
const dotenv = require("dotenv");
const mongoose = require("mongoose");
const morgan = require("morgan");
const app = require("./app");
dotenv.config({ path: "./config.env" });
const DB = process.env.DATABASE.replace(
"<password>",
process.env.DATABASE_PASSWORD
);
mongoose
.connect(DB, {
useNewUrlParser: true,
useCreateIndex: true,
useFindAndModify: false,
useUnifiedTopology: true,
})
.then(() => {
console.log("Connection to Database succesful 🎉");
});
const portNumber = 8080;
app.use(morgan("dev"));
app.listen(portNumber, "127.0.0.1", () => {
// eslint-disable-next-line no-console
console.log(`Server is now running on port ${portNumber} âš¡`);
});
The problem
When I write app.use(morgan("dev")) in the app.js file it works, but when I write it in the server.js file (the way I have pasted my code above) it does not work and doesn't even give any errors.
When you put it in your server.js file, it's the very last route/middleware declaration. That means it never gets called except when no other route has taken the request.
Middleware that you want to get called for all routes must be defined BEFORE any of the route definitions that you want it to run before. The order of registering these matters.
In my opinion, middleware like this belongs in your app.js file so you can register this middleware first, right after you create the app object and before any other routes.
I'm using node.js to build a REST CRUD, and to check if my urls are working i'm trying to get a "Hello1" message when I acess the url "localhost:5000/users", but all I get when I acess it is Cannot GET /users. I really don't know what's wrong with my code, because i'm following exactly what the tutorial says. Does anybody know what's going on?
users.js file:
import express from 'express';
const router = express.Router();
router.get('/' , (req,res) => {
res.send("Hello1");
});
export default router;
//////////////////////////////////////
index.js file
import express from 'express';
import bodyParser from 'body-parser';
import usersRoutes from './routes/users.js';
const app = express();
const PORT = 5000;
app.use(bodyParser.json());
app.get('/', (req,res) => {
res.send("hello");
})
app.get('/users', usersRoutes);
app.listen(PORT, () => console.log("Server running on localhost:"+PORT));
Instead of:
app.get('/users', usersRoutes);
You should use:
app.use('/users', usersRoutes);
I made a server with node js, and my localhost:4000 worked well before. And then, I wrote many codes after it. But my localhost:4000 doesn't work now. Please let me know what's wrong with it.
app.js:
import express from "express";
import morgan from "morgan";
import helmet from "helmet";
import cookieParser from "cookie-parser";
import bodyParser from "body-parser";
import userRouter from "./routers/userRouter";
import videoRouter from "./routers/videoRouter";
import globalRouter from "./routers/globalRouter";
import routes from "./routes";
const app = express();
const PORT = 4000;
function handleListening() {
console.log(`listening http://localhost:${PORT}`);
}
app.listen(PORT, handleListening);
app.use(cookieParser());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(helmet());
app.use(morgan("dev"));
app.use("routes", globalRouter);
app.use("routes.users", userRouter);
app.use("routes.videos", videoRouter);
export default app;
init.js:
import app from "./app";
const PORT = 4000;
const handleListening = () =>
console.log(`Listening on: http://localhost:${PORT}`);
app.listen(PORT, handleListening);
Only one process can be bound to a port at a time. You are trying to start your sever twice at port 4000. You should be getting an error saying this.
If you want init.js to handle starting the server, remove
app.listen(PORT, handleListening);
from app.js and you should be good.