我正在使用NestJS + Prisma + Apollo Federation。
在微服务A上定义用户,在微服务B上定义帖子。 关系是1-N,一个用户可以有N个帖子。
在Prisma中,由于userId是一个uuid,因此Post的数据模型是使用用户的String定义的。
type Post {
id: Int! @id
createdAt: DateTime! @createdAt
updatedAt: DateTime! @updatedAt
user: String!
}
在生成的模式(带有https://graphql-code-generator.com)中,Post具有类型为User的属性,而该类型的User扩展了id和一组帖子:
type Post @key(fields: "id") {
id: Int!
createdAt: DateTime!
updatedAt: DateTime!
user: User!
}
extend type User @key(fields: "id") {
id: ID! @external
posts: [Post]
}
在阿波罗联盟中,所有工作均按预期进行,除非进行查询以尝试在两个微服务之间进行链接。
在操场上,如果尝试在不设置子字段的情况下用其用户查询帖子,则会破坏架构并说您必须设置User的子字段,如果设置了子字段,graphql会显示一条消息,提示您无法使用子字段因为它的类型是String。
我可以正确执行此操作的唯一方法是在Prisma中设置字符串类型的userId字段,并在模式中设置另一个名为User类型的用户的字段。但是所有示例都没有显示使用db的字段和使用架构的字段。
我的问题是建议这样做还是我错过了什么?
答案 0 :(得分:0)
为了从User
获取Post
,必须在帖子和用户服务中创建一个解析器。
邮政服务
const resolvers = {
Post:{//before you do this you have to extend User schema which you already did.
// you are basically asking the 'User' service, which field should be used to query user.
user: ref => ({ __typename: 'User', id: ref.userId })
}
Query:{
// query resolvers
},
Mutation:{
// mutation resolvers
}
用户服务
const resolvers = {
User:{//the code below allows other services to extend User in their own schemas
__resolveReference: (ref, { userDataLoader }) => userDataLoader.load(ref.id),
}
Query:{
// query resolvers
},
Mutation:{
// mutation resolvers
}
现在,像[Post]
这样的链接数组必须完全在邮政服务中完成
邮政服务
const resolvers = {
Post:{//before you do this you have to extend User schema which you already did.
// you are basically telling the user service, which field should be used to query user.
user: ref => ({ __typename: 'User', id: ref.user })
},
User:{
posts:(ref, args, {postDataLoader}) => getOrders(ref.postIds) //or ref.userId(foreign key)
},
Query:{
// query resolvers
},
Mutation:{
// mutation resolvers
}