合并 Apollo Server 的 GraphQL 解析器不适用于 Object.assign()
Merging GraphQL Resolvers for Apollo Server not working with Object.assign()
我正在为 GraphQL API 模块化我的架构,并尝试在不使用任何第 3 方库的情况下合并解析器。
有没有不用 Lodash.merge()
或等效方法的简单方法?
Apollo 文档说使用 Lodash 等库来 merge()
模块化解析器。 (http://dev.apollodata.com/tools/graphql-tools/generate-schema.html#modularizing)
问题似乎是,就其本质而言,解析器包含函数作为属性,因此当我通过 Object.assign()
甚至 JSON.stringify()
.[=24= 访问它们时,它们似乎被省略了]
如果我 console.log 他们,我会看到:{"Query":{},"Mutation":{}}
下面是其中一个解析器的样子:
const productResolvers = {
Query: {
myProducts: (root, { userId }, context) => {
return [
{ id: 1, amount: 100, expiry: '12625383984343', created: '12625383984343' },
{ id: 2, amount: 200, expiry: '12561351347311', created: '12625383984343' },
{ id: 3, amount: 200, expiry: '11346347378333', created: '12625383984343' },
{ id: 4, amount: 350, expiry: '23456234523453', created: '12625383984343' },
];
},
},
Mutation: {
addProduct: (root, { userId }, context) => {
return { id: 350, amount: 100, expiry: '12625383984343', created: '12625383984343' };
},
}
};
让我们假设还有另一个几乎相同的叫做 widgetResolvers
。
这是一个功能齐全的代码块:
export const schema = makeExecutableSchema({
typeDefs: [queries, mutations, productSchema, widgetSchema],
resolvers
});
这是我想要实现的目标:
export const schema = makeExecutableSchema({
typeDefs: [queries, mutations, productSchema, widgetSchema],
resolvers: Object.assign({}, productResolvers, widgetResolvers)
});
我还没有加载使用 rest spread 的能力 (https://babeljs.io/docs/plugins/transform-object-rest-spread/)。我怀疑它不会因为同样的原因 Object.assign()
不起作用。
哦,这就是我怀疑此合并不起作用的原因:Why doesn't JSON.stringify display object properties that are functions?
如果您使用 Object.assign()
,您的 Query 和 Mutation 属性不应最终为空,但您会 运行 遇到问题,因为与 lodash 的 merge()
不同,它是不是递归的。 Object.assign()
只比较它所传递的对象的 "direct" 属性——当它在列表中移动时会覆盖先前源的属性。
因为 Query
和 Mutation
是被传递对象的属性,每个后续的解析器都会覆盖前一个对象的 Query
和 Mutation
,结果对象只持有传入 Object.assign()
.
的最后一个对象的 Query 和 Mutation 属性
它不太整洁,但如果您决心避免导入 lodash,您可以通过这种方式获得预期的行为:
const productResolver = {
Query: { ... ✂ ... },
Mutation: { ... ✂ ... }
}
const widgetResolver = {
Query: { ... ✂ ... },
Mutation: { ... ✂ ... }
}
const resolvers = {
Query: Object.assign({}, widgetResolver.Query, productResolver.Query),
Mutation: Object.assign({}, widgetResolver.Mutation, productResolver.Mutation)
}
也有类型解析器吗?没问题:
const Widget = { ... ✂ ... }
const Product = { ... ✂ ... }
const resolvers = Object.assign(
{
Query: Object.assign({}, widgetResolver.Query, productResolver.Query),
Mutation: Object.assign({}, widgetResolver.Mutation, productResolver.Mutation)
},
Widget,
Product)
我正在为 GraphQL API 模块化我的架构,并尝试在不使用任何第 3 方库的情况下合并解析器。
有没有不用 Lodash.merge()
或等效方法的简单方法?
Apollo 文档说使用 Lodash 等库来 merge()
模块化解析器。 (http://dev.apollodata.com/tools/graphql-tools/generate-schema.html#modularizing)
问题似乎是,就其本质而言,解析器包含函数作为属性,因此当我通过 Object.assign()
甚至 JSON.stringify()
.[=24= 访问它们时,它们似乎被省略了]
如果我 console.log 他们,我会看到:{"Query":{},"Mutation":{}}
下面是其中一个解析器的样子:
const productResolvers = {
Query: {
myProducts: (root, { userId }, context) => {
return [
{ id: 1, amount: 100, expiry: '12625383984343', created: '12625383984343' },
{ id: 2, amount: 200, expiry: '12561351347311', created: '12625383984343' },
{ id: 3, amount: 200, expiry: '11346347378333', created: '12625383984343' },
{ id: 4, amount: 350, expiry: '23456234523453', created: '12625383984343' },
];
},
},
Mutation: {
addProduct: (root, { userId }, context) => {
return { id: 350, amount: 100, expiry: '12625383984343', created: '12625383984343' };
},
}
};
让我们假设还有另一个几乎相同的叫做 widgetResolvers
。
这是一个功能齐全的代码块:
export const schema = makeExecutableSchema({
typeDefs: [queries, mutations, productSchema, widgetSchema],
resolvers
});
这是我想要实现的目标:
export const schema = makeExecutableSchema({
typeDefs: [queries, mutations, productSchema, widgetSchema],
resolvers: Object.assign({}, productResolvers, widgetResolvers)
});
我还没有加载使用 rest spread 的能力 (https://babeljs.io/docs/plugins/transform-object-rest-spread/)。我怀疑它不会因为同样的原因 Object.assign()
不起作用。
哦,这就是我怀疑此合并不起作用的原因:Why doesn't JSON.stringify display object properties that are functions?
如果您使用 Object.assign()
,您的 Query 和 Mutation 属性不应最终为空,但您会 运行 遇到问题,因为与 lodash 的 merge()
不同,它是不是递归的。 Object.assign()
只比较它所传递的对象的 "direct" 属性——当它在列表中移动时会覆盖先前源的属性。
因为 Query
和 Mutation
是被传递对象的属性,每个后续的解析器都会覆盖前一个对象的 Query
和 Mutation
,结果对象只持有传入 Object.assign()
.
它不太整洁,但如果您决心避免导入 lodash,您可以通过这种方式获得预期的行为:
const productResolver = {
Query: { ... ✂ ... },
Mutation: { ... ✂ ... }
}
const widgetResolver = {
Query: { ... ✂ ... },
Mutation: { ... ✂ ... }
}
const resolvers = {
Query: Object.assign({}, widgetResolver.Query, productResolver.Query),
Mutation: Object.assign({}, widgetResolver.Mutation, productResolver.Mutation)
}
也有类型解析器吗?没问题:
const Widget = { ... ✂ ... }
const Product = { ... ✂ ... }
const resolvers = Object.assign(
{
Query: Object.assign({}, widgetResolver.Query, productResolver.Query),
Mutation: Object.assign({}, widgetResolver.Mutation, productResolver.Mutation)
},
Widget,
Product)