131 lines
3.7 KiB
JavaScript
131 lines
3.7 KiB
JavaScript
// 1. 导入依赖
|
|
require('dotenv').config(); // 尽早加载环境变量
|
|
const fastify = require('fastify')({ logger: true }); // 开启日志,方便调试
|
|
const { ObjectId } = require('mongodb'); // 导入 ObjectId 用于ID操作
|
|
|
|
// 2. 注册 MongoDB 插件
|
|
// Fastify 的插件系统能确保在路由处理前,数据库连接已经准备就绪
|
|
fastify.register(require('./db-connector'));
|
|
|
|
// ------------------- API 路由定义 -------------------
|
|
|
|
/**
|
|
* @api {post} /todos 创建一个新的 Todo
|
|
*/
|
|
fastify.post('/todos', async (request, reply) => {
|
|
// fastify.mongo.db 是由我们的插件注入的
|
|
const todosCollection = fastify.mongo.db.collection('todos');
|
|
|
|
// 从请求体中获取数据
|
|
const { text, completed = false } = request.body;
|
|
|
|
if (!text) {
|
|
return reply.code(400).send({ message: '`text` 字段是必需的。' });
|
|
}
|
|
|
|
const newTodo = {
|
|
text,
|
|
completed,
|
|
createdAt: new Date(),
|
|
};
|
|
|
|
const result = await todosCollection.insertOne(newTodo);
|
|
reply.code(201).send(result); // 201 Created
|
|
});
|
|
|
|
/**
|
|
* @api {get} /todos 获取所有 Todos
|
|
*/
|
|
fastify.get('/todos', async (request, reply) => {
|
|
const todosCollection = fastify.mongo.db.collection('todos');
|
|
const todos = await todosCollection.find({}).toArray();
|
|
reply.send(todos);
|
|
});
|
|
|
|
/**
|
|
* @api {get} /todos/:id 获取单个 Todo
|
|
*/
|
|
fastify.get('/todos/:id', async (request, reply) => {
|
|
const { id } = request.params;
|
|
|
|
// 校验 ID 格式是否正确
|
|
if (!ObjectId.isValid(id)) {
|
|
return reply.code(400).send({ message: '无效的ID格式。' });
|
|
}
|
|
|
|
const objectId = new ObjectId(id);
|
|
const todosCollection = fastify.mongo.db.collection('todos');
|
|
const todo = await todosCollection.findOne({ _id: objectId });
|
|
|
|
if (!todo) {
|
|
return reply.code(404).send({ message: '未找到指定的 Todo。' });
|
|
}
|
|
|
|
reply.send(todo);
|
|
});
|
|
|
|
/**
|
|
* @api {put} /todos/:id 更新一个 Todo
|
|
*/
|
|
fastify.put('/todos/:id', async (request, reply) => {
|
|
const { id } = request.params;
|
|
const { text, completed } = request.body;
|
|
|
|
if (!ObjectId.isValid(id)) {
|
|
return reply.code(400).send({ message: '无效的ID格式。' });
|
|
}
|
|
|
|
const objectId = new ObjectId(id);
|
|
const todosCollection = fastify.mongo.db.collection('todos');
|
|
|
|
const updateDoc = { $set: {} };
|
|
if (text !== undefined) updateDoc.$set.text = text;
|
|
if (completed !== undefined) updateDoc.$set.completed = completed;
|
|
|
|
// 如果没有提供任何更新字段,则返回错误
|
|
if (Object.keys(updateDoc.$set).length === 0) {
|
|
return reply.code(400).send({ message: '请提供需要更新的字段 (text 或 completed)。' })
|
|
}
|
|
|
|
const result = await todosCollection.updateOne({ _id: objectId }, updateDoc);
|
|
|
|
if (result.matchedCount === 0) {
|
|
return reply.code(404).send({ message: '未找到指定的 Todo 进行更新。' });
|
|
}
|
|
|
|
reply.send({ message: 'Todo 更新成功。' });
|
|
});
|
|
|
|
/**
|
|
* @api {delete} /todos/:id 删除一个 Todo
|
|
*/
|
|
fastify.delete('/todos/:id', async (request, reply) => {
|
|
const { id } = request.params;
|
|
|
|
if (!ObjectId.isValid(id)) {
|
|
return reply.code(400).send({ message: '无效的ID格式。' });
|
|
}
|
|
|
|
const objectId = new ObjectId(id);
|
|
const todosCollection = fastify.mongo.db.collection('todos');
|
|
const result = await todosCollection.deleteOne({ _id: objectId });
|
|
|
|
if (result.deletedCount === 0) {
|
|
return reply.code(404).send({ message: '未找到指定的 Todo 进行删除。' });
|
|
}
|
|
|
|
reply.code(200).send({ message: 'Todo 删除成功。' });
|
|
});
|
|
|
|
// 3. 启动服务器
|
|
const start = async () => {
|
|
try {
|
|
await fastify.listen({ port: 3000 });
|
|
fastify.log.info(`服务器运行在 ${fastify.server.address().port}`);
|
|
} catch (err) {
|
|
fastify.log.error(err);
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
start(); |