reactjs - การแยกคำสั่ง Prisma ที่ซับซ้อนในแอป Next.js
ฉันมีแอป Next.JS ฉันต้องการเรนเดอร์ฟีดรายการงานในหน้าแรก แต่ก็ต้องการในหน้าผู้ใช้ด้วย ฉันติดขัดเล็กน้อยเกี่ยวกับวิธีการแยกคำสั่ง Prisma ของฉัน
ฉันดึงวัตถุข้อมูลขนาดใหญ่โดยใช้ getServerSideProps และส่งสิ่งนี้ไปยังคอมโพเนนต์หน้า (และใช้ react-query เพื่อทำการ hydrate และดึงข้อมูลซ้ำ แต่ตอนนี้ไม่เกี่ยวข้อง) - getRecentTodos (รวมถึง todos) สำหรับหน้าแรกของฉัน - getUserDetailsByName (รวมถึง todos) สำหรับหน้าผู้ใช้
export type getRecentTodos = ReturnType<typeof getRecentTodos> extends Promise<
infer T
>
? T
: never
export const getRecentTodos = async (recentItemsAmount = 20) => {
return await prisma.todos.findMany({
where: { done: true },
select: {
id: true,
userId: true,
content: true,
done: true,
createdAt: true,
attachments: true,
todoReplies: {
select: {
id: true,
userId: true,
content: true,
todoReplyLikes: true,
todoId: true,
user: { select: { name: true, displayName: true, image: true } },
},
orderBy: { createdAt: 'asc' },
},
todoLikes: {
select: {
user: true,
},
},
user: {
select: {
name: true,
displayName: true,
image: true,
},
},
},
orderBy: { createdAt: 'desc' },
take: recentItemsAmount,
})
}
export const getUserDetailsByName = async (username: string) => {
return await prisma.user.findUnique({
where: {
name: username,
},
select: {
name: true,
displayName: true,
bio: true,
location: true,
twitter: true,
image: true,
createdAt: true,
todos: {
select: {
id: true,
content: true,
userId: true,
done: true,
updatedAt: true,
createdAt: true,
attachments: true,
user: true,
todoLikes: true,
todoReplies: {
take: 30,
orderBy: { createdAt: 'desc' },
select: {
id: true,
userId: true,
todoId: true,
createdAt: true,
content: true,
user: true,
},
},
},
take: 30,
orderBy: { createdAt: 'desc' },
},
projects: true,
},
})
}
ทั้งสองคำสั่งค้นหาจะส่งคืน ‘todos’ แต่สามารถส่งคืนในรูปแบบที่แตกต่างกันเล็กน้อย ส่วนประกอบฟีด todo คาดหวังให้มีคุณสมบัติบางอย่างพร้อมใช้งาน - เช่น displayName บน todoReplies - แต่ในการเรียก getUserDetailsByName displayName อาจไม่ใช่ส่วนหนึ่งของการตอบสนองหรือฝังอยู่ลึกลงไปอีกหนึ่งชั้นหรือบางอย่าง
จะทำอย่างไรไม่ให้เรื่องนี้ซับซ้อนเร็วเกินไป?
- คุณอยากเลือกงานที่ต้องทำในคำค้นหาในลักษณะเดียวกันมากหรือน้อย (ส่งกลับสิ่งเดียวกันและละเว้นสิ่งเดียวกัน ยกเว้นบางอย่างเช่นลำดับ)
- แต่การคอยปรับสิ่งเหล่านี้ให้ตรงกันด้วยมือในหลาย ๆ คำถามจะซับซ้อนอย่างรวดเร็ว
วิธีแก้ไขที่เป็นไปได้?
ฉันควรแยก getServerSideProps ออกเป็นหลายการดึงข้อมูลหรือไม่?
ดังนั้น แทนที่จะใช้ ‘getUserDetailsByName’ หนึ่งตัว ซึ่งมี todos อยู่ในรูปแบบฟิลด์ความสัมพันธ์
- ดึงรายละเอียดผู้ใช้
- ดังนั้นแทนที่จะใช้ ‘getUserDetailsByName’ หนึ่งตัวซึ่งมี todos เป็นฟิลด์ความสัมพันธ์รวมอยู่
- ดึงรายละเอียดผู้ใช้
- ดึงงานที่ต้องทำ
การใช้ Typescript เพื่อจับมันในฐานรหัสของฉันเมื่อฟังก์ชันพยายามเข้าถึงคุณสมบัติที่ไม่ได้ถูกส่งกลับจากการค้นหา Prisma เฉพาะนั้นหรือไม่? (ฉันเพิ่งเริ่มเห็นความเป็นไปได้ของ Typescript สำหรับสิ่งแบบนี้)
ฉันควรจะทำให้การสร้างงานใน Prisma query เป็นมาตรฐานด้วยฟังก์ชันแล้วรวมฟังก์ชันนั้นไว้ภายใน Prisma queries หรือไม่? คุณสามารถรวมเช่น:
const todoSelect = {
id: true,
userId: true,
content: true,
{.......}
user: {
select: {
name: true,
displayName: true,
image: true,
},
},
}
export type getRecentTodos = ReturnType<typeof getRecentTodos> extends Promise<
infer T
>
? T
: never
export const getRecentTodos = async (recentItemsAmount = 20) => {
return await prisma.todos.findMany({
where: { done: true },
select: todoSelect,
orderBy: { createdAt: 'desc' },
take: recentItemsAmount,
})
}
const userSelect = {
name: true,
{......}
todos: {
select: todoSelect,
take: 30,
orderBy: { createdAt: 'desc' },
},
projects: true,
}
export const getUserDetailsByName = async (username: string) => {
return await prisma.user.findUnique({
where: {
name: username,
},
select: userSelect,
})
}