【发布时间】:2018-08-25 08:18:47
【问题描述】:
我是 GraphQL 的新手,我正在尝试设置一个演示应用程序来向我的同事做一些介绍性的演讲。
我正在使用 NodeJS。
我想出了以下架构:
type Query {
author(id:Int!): Author
song(id:Int!): Song
}
type Author {
id:Int!
name:String!
songs(max:Int):[Song]!
}
type Song {
id:Int!
name:String!
author:Author!
}
这是与 Song.author 关联相关的解析器部分:
[...]
Song: {
author: ({ id }, args, context, info) => {
return mergeInfo.delegate(
'query',
'author',
{ id },
context,
info,
);
}
}
[...]
所以这种方法的问题是我需要将 Song.id 添加到包含查询中才能在其中包含 Song.author:
{
song(id: 1) {
id
author {
name
}
}
}
以下方法不起作用:
{
song(id: 1) {
author {
name
}
}
}
根据实施情况,它会给我一个错误或null(那会更糟)。
这迫使编写查询的人知道后端的实现细节,这显然是不好的。 :P
有没有人可以解决这个问题?有什么我忽略的吗?
我尝试使用info 对象,但这会解决问题,因为我需要的 id 是查询的一部分,但我可以想出一个场景,其中我需要的参数位于数据仅在后端可用。
更新:
按照 Daniel 的要求(谢谢),这是创建包含拼接的架构的整个测试文件:
const { makeExecutableSchema, mergeSchemas } = require('graphql-tools');
const DATA = {
authors: {
1: { id: 1, name: 'John' },
2: { id: 2, name: 'Paul' },
},
songs: {
1: { id: 1, name: 'Love me do', authorId: 1 },
2: { id: 2, name: 'I wanna be your man', authorId: 1 },
3: { id: 3, name: 'I\'ll be back', authorId: 2 },
}
};
const authorsTypes = `
type Query {
author(id:Int!): Author
}
type Author {
id:Int!
name:String!
}
`;
const authorSchema = makeExecutableSchema({
typeDefs: authorsTypes,
resolvers: {
Query: {
author: (_, { id }) => DATA.authors[id],
},
},
});
const authorsLinksTypes = `
extend type Author {
songs(max:Int):[Song]!
}
`;
const authorsLinksResolvers = mergeInfo => ({
Author: {
songs: ({ id }, args, context, info) => {
return Object.values(DATA.songs).filter(it => it.authorId === id)
}
},
});
const songsTypes = `
type Query {
song(id:Int!): Song
}
type Song {
id:Int!
name:String!
}
`;
const songsSchema = makeExecutableSchema({
typeDefs: songsTypes,
resolvers: {
Query: {
song: (_, { id }) => DATA.songs[id],
},
},
});
const songsLinksTypes = `
extend type Song {
author:Author!
}
`;
const songsLinksResolvers = mergeInfo => ({
Song: {
author: ({ id }, args, context, info) => {
return mergeInfo.delegate(
'query',
'author',
{ id },
context,
info,
);
}
},
});
module.exports = mergeSchemas({
schemas: [authorSchema, songsSchema, songsLinksTypes, authorsLinksTypes],
resolvers: mergeInfo => ({
...songsLinksResolvers(mergeInfo),
...authorsLinksResolvers(mergeInfo),
}),
});
【问题讨论】:
-
你能包含你的歌曲查询解析器吗?此外,如果您正在进行模式拼接,在您的问题中包含这些详细信息会很有帮助。
-
我建议不要在演示中使用模式拼接。模式拼接用于相当大规模的应用程序(例如 IBM 的微服务)。没有它,100 多种类型应该很容易维护。即使这样拼接只是一种解决方案,一些公司还是从它背后的服务中生成他们的类型。如果您想将某些内容分开,请查看 graphcool/import-schema
-
谢谢建议,demo我绝对不会用拼接
标签: node.js graphql graphql-js