例如,当我到达某个端点时,我遇到了有关 Express js 路由的一些问题:
http://localhost:3000/api/v1/projects/task/f9488b07-76f8-4f8a-bafb-471f99dde7b8
http://localhost:3000/api/v1/project/0592679a-93f1-467b-b2cd-4226f0668036
我收到了有关函数处理的消息,如下所示:
{
"errors": "Failed to find a project: Project ID is required"
}
但是功能上的消息
findProjectID
:
todo-service.js
/* eslint-disable no-useless-catch */
const prismaClient = require("../prisma-client");
const { ResponseError } = require("../error/error-response");
const createProject = async ({
projectname,
description,
owner,
expiresAt,
}) => {
try {
const userConnections =
Array.isArray(owner) && owner.length > 0
? owner.filter((o) => o.user_id).map((o) => ({ user_id: o.user_id }))
: null;
console.log();
// Parse the input date string using Date constructor
// Check if `expiresAt` is provided and is a valid date
const timestamp = expiresAt ? new Date(expiresAt).toISOString() : null;
if (expiresAt && isNaN(new Date(expiresAt))) {
throw new Error("Invalid date format for expiresAt.");
}
const data = {
projectname,
description,
...(timestamp && { expiresAt: timestamp }),
...(userConnections.length > 0 && {
owner: { connect: userConnections },
}),
};
const createdProject = await prismaClient.project.create({
data,
include: {
owner: {
select: {
user_id: true,
username: true,
},
}, //
},
});
return createdProject;
} catch (error) {
console.error("Error creating project:", error);
throw error;
}
};
//getvalueprojectbyownerid
const getProject = async (projectId) => {
try {
const project = await prismaClient.project.findMany({
where: {
project_id: projectId,
},
include: {
owner: {
select: {
user_id: true,
username: true, // Adjust according to your user model fields
},
},
},
});
console.log(project);
return project;
} catch (error) {
console.log(error);
}
};
//editproject
const editproject = async (project_id, projectname, description, owner) => {
try {
const findProject = await findProjectID(project_id);
console.log(findProject);
if (!findProject) {
throw new ResponseError(404,"Project ID not Found");
}
const data = {
projectname,
description,
};
if (Array.isArray(owner)) {
const connectOwners = owner
.filter((o) => o.user_id)
.map((o) => ({ user_id: o.user_id }));
if (connectOwners.length > 0) {
data.owner = {
connect: connectOwners,
};
} else {
const disconnectOwners = findProject.owner.map((o) => ({
user_id: o.user_id,
}));
if (disconnectOwners.length > 0) {
data.owner = {
disconnect: disconnectOwners,
};
}
}
}
console.log("Data to update:", data);
const projectUpdate = await prismaClient.project.update({
where: {
project_id,
},
data,
include: {
owner: {
select: {
user_id: true,
username: true,
},
},
},
});
return projectUpdate;
} catch (error) {
console.log(error);
throw new Error("Failed to update project");
}
};
//delete todo projectbyid
const deleteProjectById = async (project_id) => {
try {
const findProject = await findProjectID(project_id);
if (!findProject) {
throw new ResponseError(404, "Project Not Found");
}
const deleteProject = await prismaClient.project.delete({
where: {
project_id,
},
});
return deleteProject;
} catch (error) {
console.log(error);
}
};
//findProjecID
const findProjectID = async (project_id) => {
try {
if (!project_id) {
throw new Error("Project ID is required");
}
const project = await prismaClient.project.findUnique({
where: { project_id },
include: { owner: true },
});
return project;
} catch (error) {
console.error("Error finding a project:", error.message);
throw new Error(`Failed to find a project: ${error.message}`);
}
};
//Task
const createTask = async ({
title,
description,
status,
priority,
projectId,
assigneeId,
expiresAt
}) => {
try {
const timestamp = expiresAt ? new Date(expiresAt).toISOString() : null;
if (expiresAt && isNaN(new Date(expiresAt))) {
throw new Error("Invalid date format for expiresAt.");
}
const createTasks = await prismaClient.task.create({
data: {
title : title || null,
description : description || null,
status : status || null,
priority: priority || null,
project: projectId
? { connect: { project_id: projectId } }
: undefined,
Assignee: assigneeId
? { connect: { user_id: assigneeId } }
: undefined,
...(timestamp && { expiresAt: timestamp }),
},
include: {
Assignee: {
select: {
user_id: true,
username: true,
},
},
project: {
select: {
project_id: true,
projectname: true,
},
},
},
});
return createTasks;
} catch (error) {
console.error("Error creating task:", error.message);
throw new Error(`Failed to create task: ${error.message}`);
}
};
const getTaskById = async (task_id) => {
try {
if (!task_id) {
throw new Error("task ID is required");
}
const task = await prismaClient.task.findUnique({
where: { task_id : task_id},
include : {
project : {
select : {
projectname : true
}
},
Assignee : {
select : {
username : true
}
}
},
});
return task;
} catch (error) {
throw error;
}
};
const editTask = async (task_id, title, description, status, priority, projectId, assigneeId, expiresAt) => {
try {
const findTask = await findTaskById(task_id);
if (!findTask) {
throw new ResponseError(404, "Task not found");
}
const timestamp = expiresAt ? new Date(expiresAt).toISOString() : null;
const editedTask = await prismaClient.task.update({
where: {
task_id
},
data: {
title: title || null,
description: description || null,
status: status || null,
priority: priority || null,
project: projectId
? { connect: { project_id: projectId } }
: { disconnect: true },
Assignee: assigneeId
? { connect: { user_id: assigneeId } }
: { disconnect: true },
...(timestamp && { expiresAt: timestamp }),
},
include: {
Assignee: {
select: {
user_id: true,
username: true,
},
},
project: {
select: {
project_id: true,
projectname: true,
},
},
},
});
return editedTask;
// eslint-disable-next-line no-unused-vars
} catch (error) {
console.error("Error finding a project:", error.message);
throw new Error("Failed to Edit Task");
}
};
const deleteTask = async(taskid) => {
try {
if(!taskid) {
throw new ResponseError(404, "task id is required!")
}
const findTaskId = await findTaskById(taskid)
console.log("idne apa :: ",findTaskId)
if(!findTaskId){
throw new ResponseError(404, "task id not found")
}
const deleteTask = await prismaClient.task.delete({
where : {
task_id : taskid
}
})
return deleteTask
} catch (error) {
throw error
}
}
const findTaskById = async (task_id) => {
try {
if (!task_id) {
throw new ResponseError(404,"task Id is required");
}
const task = await prismaClient.task.findUnique({
where: { task_id : task_id},
});
if (!task) {
throw new ResponseError(404,"Task id not found");
}
return task;
} catch (error) {
throw error;
}
};
module.exports = {
createProject,
getProject,
editproject,
deleteProjectById,
findProjectID,
createTask,
getTaskById,
editTask,
deleteTask,
findTaskById
};
它是一个控制器文件:
todo-controller.js
const { createProject, getProject, editproject, deleteProjectById, findProjectID, createTask, getTaskById, editTask, findTaskById, deleteTask} = require("../services/todo-services");
const createProjectHandler = async (req, res , next) => {
try {
const {projectname, description, owner,expiresAt} = req.body
console.log("Request body:", req.body);
if (!owner) {
throw new Error('User ID is required for connecting an owner.');
}
const createNewProject = await createProject({
projectname,
description,
owner,
expiresAt
});
res.status(201).json({status : 201,
data: createNewProject
})
} catch (error) {
console.log(error)
next(error)
}
}
const getProjectByIdHandler = async ( req, res , next) => {
try {
const projectId = req.params.projectId
if (!projectId) {
return res
.status(400)
.json({ error: "Invalid project ID", message: "Invalid Request" });
}
const project = await getProject(projectId)
if(!project){
return res.status(404).json({ error: "Project not found", message: "No project found for the given owner ID" });
}
return res.status(200).json(project);
} catch (error) {
console.log(error)
next()
}
}
const editProjectHandler = async ( req, res, next ) => {
try {
const projectId = req.params.projectId
const {projectname, description, owner} = req.body
console.log("project ID :: " ,projectId)
if(!projectId) {
return res
.status(400)
.json({ error: "Invalid Project ID", message: "Invalid Request" });
}
const updateProject = await editproject(projectId,projectname,description,owner)
return res.status(201).json({message : "Project Succesfully to Update",updateProject})
} catch (error) {
console.log(error)
next (error)
}
}
//delete handler project
const deleteProjectHandler = async (req, res, next) => {
try {
const projectId = req.params.projectId;
// Await the result of findProjectID to ensure it completes
const findProject = await findProjectID(projectId);
if (!findProject) {
return res.status(404).json({ error: "Invalid Project ID", message: "Project not found" });
}
// Proceed to delete the project
await deleteProjectById(projectId);
// Return 204 No Content status as the deletion was successful
return res.status(204).send();
} catch (error) {
// Log the error for debugging
console.error("Delete Project Handler Error:", error);
// Forward the error to the error handling middleware
next(error);
}
};
const createTaskHandler = async(req, res, next) => {
try {
const {title, description,status, priority,projectId,assigneeId, expiresAt} = req.body
const newTask = await createTask({title, description,status, priority,projectId,assigneeId,expiresAt})
console.log("newtask :: ", newTask)
res.status(201).json({status : 201,
data: newTask
})
} catch (error) {
next(error)
}
}
const getTaskByIdHandler = async (req, res, next) => {
try {
const task_id = req.params.taskId;
// Check if taskId is provided
if (!task_id) {
return res.status(400).json({ status: 400, error: "Task ID is required" });
}
// Find the task by ID
const task = await getTaskById(task_id);
if (!task) {
return res.status(404).json({ status: 404, error: "Task Not Found" });
}
// Return the found task
res.status(200).json({
status: 200,
data: task,
});
} catch (error) {
next(error); // Pass the error to the error handling middleware
}
};
const editTaskHandler = async(req, res, next) => {
try {
const taskId = req.params.taskId
console.log("task id :: ", taskId)
const { title, description, status, priority,projectId,assigneeId, expiresAt} = req.body
console.log("body ?? :: ",req.body)
if(!taskId || taskId.trim() === ""){
return res.status(404).json({status: 404, message : "taskid required!"})
}
const findTask = await findTaskById(taskId)
if(!findTask) {
return res.status(404).json({status: 200, message : "taskid not found!"})
}
const editNewTask = await editTask(taskId,title, description, status, priority,projectId,assigneeId, expiresAt)
res.status(200).json({status : 200, message: "updated successfull!", editNewTask})
} catch (error) {
console.error("Error in editTaskHandler:", error.message);
next(error)
}
}
const deleteTaskHandler = async(req, res, next) => {
try {
const task_id = req.params.taskId
console.log("paramsid ::", req.params.taskId)
if(!task_id){
return res.status(404).json({
status : 404,
message : "task id is required!"
})
}
await deleteTask(task_id)
return res.status(204).json().send
} catch (error) {
console.error("Error in editTaskHandler:", error.message);
next(error)
}
}
module.exports = {
createProjectHandler,
getProjectByIdHandler,
editProjectHandler,
deleteProjectHandler,
createTaskHandler,
getTaskByIdHandler,
editTaskHandler,
deleteTaskHandler
}
其路线文件
const express = require("express");
const { authenticationMiddleware } = require("../middleware/auth-middleware");
const {
createProjectHandler,
getProjectByIdHandler,
editProjectHandler,
deleteProjectHandler,
createTaskHandler,
getTaskByIdHandler,
editTaskHandler,
} = require("../controller/todo-controller");
const todoRouter = express.Router();
todoRouter.use(authenticationMiddleware);
//project
todoRouter.post("/project", createProjectHandler);
todoRouter.get("/project/:projectId", getProjectByIdHandler);
todoRouter.put("/project/:projectId?", editProjectHandler);
todoRouter.delete("/project/:projectId", deleteProjectHandler);
//task
todoRouter.post("/project/task/", createTaskHandler);
todoRouter.get("/project/task/:taskId", getTaskByIdHandler);
todoRouter.put("/project/task/:taskId?", editTaskHandler);
todoRouter.delete("/project/task/:taskId?", deleteProjectHandler);
module.exports = todoRouter;
我正在尝试改变它的工作路线,例如:
方法更新之前
http://localhost:3000/api/v1/projects/task/taskid
方法更新后
http://localhost:3000/api/v1/projects/task/:taskId
但是当我使用 metode delete 像
创建新路线时http://localhost:3000/api/v1/projects/task/:taskId
它不起作用,输出是这样的
{
"errors": "Failed to find a project: Project ID is required"
}
帮助我进行最佳实践以进行正确的路由
由于中间件是按照加载顺序执行的,请尝试将具体路由移至带参数的路由之前,即将任务路由移至项目之前:
//task
todoRouter.post("/project/task/", createTaskHandler);
todoRouter.get("/project/task/:taskId", getTaskByIdHandler);
todoRouter.put("/project/task/:taskId?", editTaskHandler);
todoRouter.delete("/project/task/:taskId?", deleteProjectHandler);
//project
todoRouter.post("/project", createProjectHandler);
todoRouter.get("/project/:projectId", getProjectByIdHandler);
todoRouter.put("/project/:projectId?", editProjectHandler);
todoRouter.delete("/project/:projectId", deleteProjectHandler);