什么是好的GraphQL查询模式?



GraphQL查询的好模式是什么?

考虑以下情况(idemail保证唯一)。

第一个模式,查询名称告诉您期望的参数:

getUserById(id)
getUserByEmail(email)

vs单个查询可以处理任意一个变量:

getUser({ id })
getUser({ email })

在此场景中,解析器将选择字段并根据该字段进行查询。

一些优点/缺点:

  • pro:对两种类型使用一个查询可以更灵活地添加更多字段,而不是为每种类型创建新的查询。
  • pro:使用一个查询更容易理解,而不是寻找不同的接口。
  • pro:如果用户想动态地改变类型,你不需要再写一个查询。
  • con:验证必须在解析器中手动处理。
  • con:解析器的后端复杂性增加。

我在一个项目中有一些类似的查询,我倾向于使用第二种模式。由于我使用了knex形式,所以我的解析器的复杂性没有增加。只是:

getUser: (parent,args,context) => knex('user').where(args).first()

由于GraphQL查询定义,我可以依赖于将参数限制为具有特定类型的某些键。

query getUser(id: ID, email: emailType): User

对于保证结果唯一的参数,这是可以的。如果参数可能产生非唯一的答案,那么您可能希望以不同的方式处理它们。还有一个问题是,如果idemail在您的情况下不指向相同的记录,该怎么办?

当然,因为idemail都是可选的,所以根本不提供参数的情况很小。GraphQL没有提供指定的方法,必须提供至少一个参数。每个参数都是单独需要或不需要的。

如果您不亲自编写解析器和客户端查询,则可能希望以不同的方式处理此问题,因为随机客户端可能会发送违反您假设的查询。

如果您可以将id查询作为所有对象的默认模式,并且对于任何特殊情况,将有一个描述性查询名称。

这通过默认模式满足了90%的需求。当你需要的时候就破例吧。

getUser(id)
getUserByEmail(email)
getCompany(id)
getCompanyByName(name)
@Query(() => UserDto, { description: 'Get other user info' })
async user(@UserDecorator() currentUser: User, @Args('id') id: string) {
return await this.prisma.user.findUnique({ where: { id } });
}
@Query(() => UserDto, { description: 'Get other user info by Email' })
async userByEmail(@UserDecorator() currentUser: User, @Args('email') email: string) {
return await this.prisma.user.findUnique({ where: { email } });
}

或者,如前所述,将所有变量作为可选的传入,并让后端处理它。

// everything is optional, and each unique
@InputType()
export class UserWhereUniqueInput implements Partial<User> {
@Field(() => ID, { nullable: true })
id?: string;
@Directive('@lowercase')
@Field(() => String, { nullable: true })
email?: string;
@Directive('@lowercase')
@Field(() => String, { nullable: true })
username?: string;
}

// on the backend, just let the ORM take the input as received
async user(userWhereUniqueInput: UserWhereUniqueInput): Promise<User | null> {
return this.prisma.user.findUnique({ where: userWhereUniqueInput });
}

参考:https://github.com/neekware/fullerstack

https://github.com/neekware/fullerstack/blob/916cf1031af0e077d339a3fbdad04eeb32fc3884/libs/nsx-user/src/lib/user.model.ts L155

https://github.com/neekware/fullerstack/blob/916cf1031af0e077d339a3fbdad04eeb32fc3884/libs/nsx-user/src/lib/user.resolver.ts L64

https://github.com/neekware/fullerstack/blob/916cf1031af0e077d339a3fbdad04eeb32fc3884/libs/nsx-user/src/lib/user.service.ts L40

最新更新