无法在 GraphQL 中返回关系数据
Posted
技术标签:
【中文标题】无法在 GraphQL 中返回关系数据【英文标题】:Trouble Returning Relational Data in GraphQL 【发布时间】:2018-11-03 16:40:00 【问题描述】:我正在创建一个 Reddit 克隆,并且我首先设置了后端,但在创建关系数据时遇到了问题。
当我使用这个查询时:
query
subreddit(id: 1)
name
posts
title
我希望:
"data":
"subreddit":
"name": "javascript"
"posts": [
"title": "JS Post"
]
我得到了什么:
"data": null,
"errors": [
"message": "Cannot return null for non-nullable field Subreddit.posts.",
"locations": [
"line": 4,
"column": 5
],
"path": [
"subreddit",
"posts"
]
]
这是架构:
type Query
subreddits: [Subreddit!]!
subreddit(id: ID!): Subreddit!
posts: [Post!]!
post(id: ID!): Post!
type Mutation
createSubreddit(
name: String!
description: String!
contentType: String!
ageRestriction: Boolean!
): Subreddit!
type Subreddit
id: ID!
name: String!
description: String!
contentType: String!
ageRestriction: Boolean!
posts: [Post!]!
type Post
id: ID!
title: String!
body: String!
subredditId: ID!
# userId: ID!
这里是server/index.js
:
const GraphQLServer = require('graphql-yoga');
let dummySubreddits = [
name: 'javascript',
description: 'all things javascript',
contentType: 'any',
ageRestriction: false,
id: 1
,
name: 'react',
description: 'all things react',
contentType: 'any',
ageRestriction: false,
id: 2
,
name: 'primsa',
description: 'all things prisma',
contentType: 'any',
ageRestriction: false,
id: 3
];
let idCountSubreddit = dummySubreddits.length;
let dummyPosts = [
title: 'JS Post', body: 'Body of post one', id: 1, subredditId: 1 ,
title: 'React Post', body: 'Body of post two', id: 2, subredditId: 2 ,
title: 'Prisma Post',
body: 'Body of post three',
id: 3,
subredditId: 3
];
let idCountPost = dummyPosts.length;
const resolvers =
Query:
subreddits: () => dummySubreddits,
subreddit: (parent, args) =>
return dummySubreddits.find(obj => obj.id == args.id);
,
posts: () => (parent, args) =>
return dummyPosts.find(obj => obj.subredditId == parent.id);
,
post: (parent, args) =>
return dummyPosts.find(obj => obj.id == args.id);
,
Mutation:
createSubreddit: (parent, args) =>
let subreddit =
id: idCountSubreddit++,
name: args.name,
description: args.description,
contentType: args.contentType,
ageRestriction: args.ageRestriction
;
return subreddit;
;
const server = new GraphQLServer( typeDefs: './schema.graphql', resolvers );
server.start(() => console.log('Server is running on localhost:4000'));
我正在使用 GraphQL 桌面应用进行查询,但我没有 grapql-yoga
配置文件。
我哪里错了?我想指出正确的方向,以便我自己弄清楚。这是我第一次单独使用 GraphQL,在 YouTube 上做了一些教程之后,但是他们使用了graphql-express
,而我正在使用graphql-yoga
。
【问题讨论】:
您已经显示了预期的结果,但不是您实际看到的结果,也不是您进行查询时返回的错误。看看你实际上是如何进行查询的也很好(实际的查询是什么,你是通过客户端、GraphiQL、Postman 之类的工具将它发送到服务器吗?)另外,你还没有包括你的解析器或者你的 graphql-yoga 配置 @DanielRearden 哦,我忘了补充。我将编辑问题以包含它。我正在使用 GraphQL 桌面 app。我已经包括了解析器。它们在const resolvers = ...
里面,它在server/index.js
里面。我没有配置文件。
我的意思是你应该包括你如何配置你的GraphQLServer
实例:)
【参考方案1】:
将您为Query
的posts
编写的解析器移动到Subreddit
以解析那里的帖子字段。如果您的解析器不符合默认的解析器实现:
(parent) => parent[fieldName]
就像你的情况
(parent) => parent.posts
您必须自己指定。如果您在 Query
上的字段 posts
应该显示所有您可能想要针对以下实现的帖子:
const resolvers =
Query:
subreddits: () => dummySubreddits,
subreddit: (parent, args) =>
return dummySubreddits.find(obj => obj.id == args.id);
,
posts: () => dummyPosts,
post: (parent, args) =>
return dummyPosts.find(obj => obj.id == args.id);
,
Subreddit:
posts: () => (parent, args) =>
dummyPosts.filter(obj => obj.subredditId == parent.id),
,
Mutation:
createSubreddit: (parent, args) =>
let subreddit =
id: idCountSubreddit++,
name: args.name,
description: args.description,
contentType: args.contentType,
ageRestriction: args.ageRestriction
;
return subreddit;
;
【讨论】:
你是对的。这就是问题所在。一位朋友想通了,但无论如何感谢您抽出宝贵时间提供帮助!【参考方案2】:我必须为subreddit
添加一个解析器来处理posts
。
const resolvers =
Query:
subreddits: () => dummySubreddits,
subreddit: (parent, args) =>
return dummySubreddits.find(obj => obj.id == args.id);
,
posts: (parent, args) =>
return dummyPosts;
,
post: (parent, args) =>
return dummyPosts.find(obj => obj.id == args.id);
,
Mutation:
createSubreddit: (parent, args) =>
let subreddit =
id: idCountSubreddit++,
name: args.name,
description: args.description,
contentType: args.contentType,
ageRestriction: args.ageRestriction
;
return subreddit;
,
// This resolver was needed
Subreddit:
posts: subreddit =>
dummyPosts.filter(obj => obj.subredditId == subreddit.id)
;
【讨论】:
以上是关于无法在 GraphQL 中返回关系数据的主要内容,如果未能解决你的问题,请参考以下文章
我们如何从 GraphQL 的 RequestContextHolder 获取 GraphQL 的 HttpServletRequest(DefaultGlobalContext)(使用 graphq
Apollo GraphQL:用于查询返回不同类型对象的模式?