我正在使用Prisma实现一个GraphQL接口,以公开存储在PostgreSQL数据库中的一些数据。我的代码是受GraphQL工具(SDL-first)示例启发的。但是,这个逻辑效率很低,我想改进它。
下面是一段很小的代码,用于显示问题并要求解决方案。我的真正代码当然更复杂。
我的GraphQL模式
type Query {
allUsers: [User!]!
}
type User {
name: String!
posts: [Post!]!
}
type Post {
text: String!
author: User!
}
我的解析器对象,在Node.JS代码中
const resolvers = {
Query: {
allUsers: ()=>prisma.users.findMany()
},
User: {
posts: (user)=>prisma.posts.findMany({where:{author:user.id}})
}
};
问题
这段代码可以工作,但效率很低。假设您正在运行查询{allUsers{posts{text}}}
user.id
,而不需要user.name
或其他任何东西。问题
我知道Prisma支持(备选办法),它可以解决这两个问题。但是,我不知道如何使用GraphQL查询配置options对象。
如何从GraphQL查询中提取请求的字段列表?我如何使用这些来创建to options对象来使用Prisma执行最优的嵌套搜索?
发布于 2022-06-08 20:19:30
这个包可以帮助您解析请求信息:https://www.npmjs.com/package/graphql-parse-resolve-info
然后,您需要将其转换为可以在ORM中使用的可用参数。
下面是NestJS的一个示例:
import {createParamDecorator, ExecutionContext} from '@nestjs/common';
import {GqlExecutionContext} from '@nestjs/graphql';
import {GraphQLResolveInfo} from 'graphql';
import {parseResolveInfo, ResolveTree} from 'graphql-parse-resolve-info';
export type PrismaSelect = {
select: {
[key: string]: true | PrismaSelect;
};
};
export const Relations = createParamDecorator(
(data: unknown, ctx: ExecutionContext) => {
const info = GqlExecutionContext.create(ctx).getInfo<GraphQLResolveInfo>();
const ast = parseResolveInfo(info);
return astToPrisma(Object.values((ast as ResolveTree).fieldsByTypeName)[0]);
},
);
export const astToPrisma = (ast: {
[str: string]: ResolveTree;
}): PrismaSelect => {
return {
select: Object.fromEntries(
Object.values(ast).map(field => [
field.name,
Object.keys(field.fieldsByTypeName).length === 0
? true
: astToPrisma(Object.values(field.fieldsByTypeName)[0]),
]),
),
};
};
那你就做:
import {Parent, Query, ResolveField, Resolver} from '@nestjs/graphql';
import {PrismaService} from '../services/prisma.service';
import {User} from '../entities/user.entity';
import {Relations} from 'src/decorators/relations.decorator';
import {Prisma} from '@prisma/client';
@Resolver(() => User)
export class UserResolver {
constructor(public prisma: PrismaService) {}
@Query(() => [User])
async usersWithRelationsResolver(
@Relations() relations: {select: Prisma.UserSelect},
): Promise<Partial<User>[]> {
return this.prisma.user.findMany({
...relations,
});
}
或者,如果您想解决N+1问题,可以使用Prisma内置findUnique
方法。请参阅https://www.prisma.io/docs/guides/performance-and-optimization/query-optimization-performance#solving-the-n1-problem
https://stackoverflow.com/questions/71650767
复制相似问题