我正在开发一个 MongoDB 项目,我需要为数据库配置服务器,任何人都可以帮助解决这些问题。 以下添加文件供参考,请回答这个问题!!
index.mjs
import express from "express";
import cors from "cors";
import dotenv from "dotenv";
import students from "./routes/students.mjs";
import auth from "./routes/auth.mjs";
dotenv.config();
const app = express();
app.use(cors());
app.use(express.json());
// Define routes
app.use("/api/students", students);
app.use("/api/auth", auth);
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack); // Log the error stack trace for debugging
res.status(500).send("Uh oh! An unexpected error occurred.");
});
// Start the server
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
auth.mjs
import express from "express";
import bcrypt from "bcrypt";
import db from "../db/conn.mjs"; // Adjust path as needed
import { ObjectId } from "mongodb";
const saltRounds = 10;
const router = express.Router();
// Helper function to validate password
async function validatePassword(password, hash) {
try {
const match = await bcrypt.compare(password, hash);
return match;
} catch (err) {
console.error(err.message);
return false;
}
}
// Sign-In Route
router.post('/signin', async (req, res) => {
try {
const { email, password } = req.body;
// Ensure MongoDB connection is established
await db();
// Check if email exists in DB
const user = await db.collection('users').findOne({ email });
if (!user) {
return res.status(400).send('User not found');
}
// Validate password
const isValidPassword = await validatePassword(password, user.password);
if (!isValidPassword) {
return res.status(400).send('Invalid password');
}
res.status(200).send('Sign in successful');
} catch (err) {
console.error(err);
res.status(500).send('An error occurred');
}
});
// Sign-Out Route
router.post('/signout', (req, res) => {
res.status(200).send('Sign out successful');
});
// Sign-Up Route
router.post('/signup', async (req, res) => {
const {
fullName, email, phone, branch,
currYear, yearOfJoining, password,
acmMemberId
} = req.body;
// Check if any required fields are missing
const errors = {};
if (!fullName) errors.fullName = "Full Name is required";
if (!email) errors.email = "Email is required";
if (!phone) errors.phone = "Phone number is required";
if (!branch) errors.branch = "Branch is required";
if (!currYear) errors.currYear = "Current year is required";
if (!yearOfJoining) errors.yearOfJoining = "Year of joining is required";
if (!password) errors.password = "Password is required";
if (!acmMemberId) errors.acmMemberId = "ACM Member ID is required";
// If there are errors, return them
if (Object.keys(errors).length > 0) {
return res.status(400).json(errors);
}
// If all required fields are present, continue with processing
try {
// Hash password
const hashedPassword = await bcrypt.hash(password, saltRounds);
// Insert new user into DB
const result = await db.collection('users').insertOne({
fullName, email, phone, branch,
currYear, yearOfJoining, password: hashedPassword,
acmMemberId, points: 0
});
res.status(201).send('User created successfully');
} catch (err) {
console.error(err);
res.status(500).send('An error occurred');
}
});
export default router;
conn.mjs
import { MongoClient } from "mongodb";
import dotenv from "dotenv";
dotenv.config();
const connectionString = `mongodb+srv://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASS}@acm-backend.jbgki1q.mongodb.net`;
const client = new MongoClient(connectionString);
let db;
(async () => {
try {
await client.connect();
db = client.db("acm-backend");
console.log("Connected to MongoDB");
} catch (e) {
console.error("Failed to connect to MongoDB", e);
}
})();
export default db;
我尝试使用 postman 进行 POST api 调用,但无法获取输出或返回所需的 json 答案。我期待将数据插入数据库。
{
"fullName": "John Doe",
"email": "[email protected]",
"phone": "1234567890",
"branch": "CSE",
"currYear": "3",
"yearOfJoining": "2020",
"password": "securepassword",
"acmMemberId": "12345",
"points": "0"
}
出现此问题的原因是,当您的路由尝试访问 MongoDB 连接(和数据库对象)时,可能无法建立它。在 conn.mjs 中,db 变量是异步分配的,在正确初始化之前可能会有延迟。
在这种情况下,一个好的做法是确保在启动服务器之前正确建立数据库连接。以下是修改设置的方法:
首先,修改您的 conn.mjs 以导出一个函数,以确保建立数据库连接并返回 db 对象。
import { MongoClient } from "mongodb";
import dotenv from "dotenv";
dotenv.config();
const connectionString = `mongodb+srv://${process.env.MONGODB_USERNAME}:${process.env.MONGODB_PASS}@acm-backend.jbgki1q.mongodb.net`;
const client = new MongoClient(connectionString);
let db;
const connectToDatabase = async () => {
if (db) {
return db;
}
try {
await client.connect();
db = client.db("acm-backend");
console.log("Connected to MongoDB");
return db;
} catch (e) {
console.error("Failed to connect to MongoDB", e);
throw e;
}
};
export default connectToDatabase;
接下来,修改index.mjs以确保服务器仅在建立数据库连接后启动。
import express from "express";
import cors from "cors";
import dotenv from "dotenv";
import students from "./routes/students.mjs";
import auth from "./routes/auth.mjs";
import connectToDatabase from "./db/conn.mjs";
dotenv.config();
const app = express();
app.use(cors());
app.use(express.json());
// Define routes
app.use("/api/students", students);
app.use("/api/auth", auth);
// Error handling middleware
app.use((err, req, res, next) => {
console.error(err.stack); // Log the error stack trace for debugging
res.status(500).send("Uh oh! An unexpected error occurred.");
});
const startServer = async () => {
try {
await connectToDatabase(); // Ensure database connection is established
const port = process.env.PORT || 3000;
app.listen(port, () => {
console.log(`Server is running on port ${port}`);
});
} catch (err) {
console.error("Failed to start server", err);
}
};
startServer();
最后,修改您的 auth.mjs 以使用在尝试使用它之前确保数据库连接的功能。
import express from "express";
import bcrypt from "bcrypt";
import connectToDatabase from "../db/conn.mjs"; // Adjust path as needed
import { ObjectId } from "mongodb";
const saltRounds = 10;
const router = express.Router();
// Helper function to validate password
async function validatePassword(password, hash) {
try {
const match = await bcrypt.compare(password, hash);
return match;
} catch (err) {
console.error(err.message);
return false;
}
}
// Sign-In Route
router.post('/signin', async (req, res) => {
try {
const { email, password } = req.body;
const db = await connectToDatabase(); // Ensure MongoDB connection is established
// Check if email exists in DB
const user = await db.collection('users').findOne({ email });
if (!user) {
return res.status(400).send('User not found');
}
// Validate password
const isValidPassword = await validatePassword(password, user.password);
if (!isValidPassword) {
return res.status(400).send('Invalid password');
}
res.status(200).send('Sign in successful');
} catch (err) {
console.error(err);
res.status(500).send('An error occurred');
}
});
// Sign-Out Route
router.post('/signout', (req, res) => {
res.status(200).send('Sign out successful');
});
// Sign-Up Route
router.post('/signup', async (req, res) => {
const {
fullName, email, phone, branch,
currYear, yearOfJoining, password,
acmMemberId
} = req.body;
// Check if any required fields are missing
const errors = {};
if (!fullName) errors.fullName = "Full Name is required";
if (!email) errors.email = "Email is required";
if (!phone) errors.phone = "Phone number is required";
if (!branch) errors.branch = "Branch is required";
if (!currYear) errors.currYear = "Current year is required";
if (!yearOfJoining) errors.yearOfJoining = "Year of joining is required";
if (!password) errors.password = "Password is required";
if (!acmMemberId) errors.acmMemberId = "ACM Member ID is required";
// If there are errors, return them
if (Object.keys(errors).length > 0) {
return res.status(400).json(errors);
}
// If all required fields are present, continue with processing
try {
const db = await connectToDatabase(); // Ensure MongoDB connection is established
// Hash password
const hashedPassword = await bcrypt.hash(password, saltRounds);
// Insert new user into DB
const result = await db.collection('users').insertOne({
fullName, email, phone, branch,
currYear, yearOfJoining, password: hashedPassword,
acmMemberId, points: 0
});
res.status(201).send('User created successfully');
} catch (err) {
console.error(err);
res.status(500).send('An error occurred');
}
});
export default router;
通过进行这些更改,您可以确保在路由中使用数据库连接之前正确建立数据库连接,从而防止出现 TypeError:无法读取未定义的属性(读取“集合”)错误。