reactjs - 在 Next.js 应用中分解复杂的 Prisma 查询
我有一个 Next.JS 应用。我想在首页渲染一个待办事项 feed,也想在用户页面上渲染。我有点不确定如何拆分我的 Prisma 查询。
我使用 getServerSideProps 获取一个大的数据对象并将其传递给页面组件(并使用 react-query 进行水合和重新获取,但现在不相关)- 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 feed 组件期望某些属性是可用的——例如 todoReplies 上的 displayName——但是在 getUserDetailsByName 中,displayName 可能不包含在响应中,或者它嵌套在更深的一层,等等
如何防止这件事很快变得复杂?
- 你或多或少想在查询中以相同的方式选择待办事项(返回相同的内容并省略相同的内容,除了某些事情比如顺序)
- 但是在大量查询中手动保持这些内容同步会很快变得复杂
可能的解决方案?
我应该把 getServerSideProps 拆分成多个获取操作吗?
所以不是一个包含 todos 作为关联字段的 'getUserDetailsByName'
- 获取用户详情
- 所以不是一个包含 todos 作为关联字段的 ‘getUserDetailsByName’
- 获取用户详细信息
- 获取待办事项
在我的代码库中使用 TypeScript 来捕获当一个函数尝试访问某个特定 Prisma 查询未返回的属性时的情况?(我现在才开始看到 TypeScript 在这类事情上的可能性)
我是否应该通过一个函数来标准化在 Prisma 查询中创建待办事项的方式,并在 Prisma 查询中包含该函数?你可以包含类似如下的内容:
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,
})
}