问题描述
我将MongoDB用作联盟Apollo GraphQL API的数据库。
(我的代码在TypeScript中)
我为__resolveReference
解析器对象创建了一个Post
方法,并且当我从user service
进行如下调用时,此方法很好用: >
User: {
...
firstPost(user: any) {
return { __typename: "Post",_id: user.firstPost };
},}
...
}
但是,当我在数组上调用它时,它不起作用。以下是我的称呼方式:
User: {
...
posts(user: any) {
user.posts.map((x: any) => {
return { __typename: "Post",_id: x };
});
},...
}
帖子__resolveReference
的代码如下:
Post: {
...
async __resolveReference(reference: any,{ db }: any) {
console.log(reference);
console.log(reference._id);
try {
let r = (await db
.collection("posts")
.findOne({ _id: new ObjectID(reference._id) })) as Post;
console.log(r.content);
return r;
} catch (err) {
console.log(err.stack);
}
},...
我知道从__resolveReference
对象上的posts
解析器调用User
时并未“命中”,因为终端中未显示console.log()
同样,仅来自posts
解析器,而不来自firstPost
。
在使__resolveReference
用于数组工作方面,我需要一些帮助。
谢谢。
解决方法
在 Apollo Federation 中,如果您想返回数组,__resolveReference
中的返回数组将无法正常工作,解决方案是创建新类型。
例如,如果您在一项服务中实施了 User
并在另一项服务中发布
User
和 Post
模型的简单表示如下:
typescript
-- User Service
type User{
id: ID!
email: String!
password: String!
}
-- Post Service
type Post{
id: ID!
content: String!
postedBy: ID!
date: Date
comments: [String]!
}
Add a reference to Post type
//define a key in Post
type Post @key(fields:"id")
//Add a field on User like
type User{
id: ID!
email: String!
password: String!
post: [Post]!
}
extend type Post @key(fields:"id"){
id: ID! @external
}
此方法无效。
一种解决方案是在 Post Service
中创建一个新类型:
type PostList @key(fields: "idUser"){
idUser: ID!
posts: [Post]!
}
PostList : {
__resolveReference(reference){
//data is a array of post
let userPost = data.filter((p)=>{p.postedBy==reference.idUser})
return {idUser: reference.idUser,posts: userPost}
}
}
在您的 User
服务中执行以下操作:
type User{
id: ID!
email: String!
password: String!
posts: PostList
}
extend type PostList @key(fields:"idUser"){
idUser: ID! @external
}
in User resolver
User : {
posts(_parent){
return {__typename: "PostList",idUser: _parent.id}
}
}
看看 __resolveReference
是否与 async/await
函数一起工作。
处理此问题的另一种方法是在 extend
服务上User
Post
类型。
我在这个例子中使用了 prisma,你可以使用任何 fetch 函数来解析你的数据,但做法是一样的。
邮政服务
const resolvers = {
User: {
posts: async (root: any) => await prisma.post.findMany({ where: { userId: root.id } }),},};
const typeDefs = gql`
type Post {
id: ID!
}
extend type User @key(fields: "id") {
id: ID! @external
posts: [Post]!
}
`
用户服务
const resolvers = {
Query: {
user: async (_root: any,args: any) => await prisma.user.findUnique({ where: { id: args.id } })
},User: {
__resolveReference: async (root: any) => await prisma.user.findUnique({ where: { id: root.id } }),};
const typeDefs = gql`
type Query {
user(id: ID!): User
}
type User @key(fields: "id") {
id: ID!
}
`