📅  最后修改于: 2023-12-03 15:01:03.991000             🧑  作者: Mango
如果你正在使用 TypeScript 和 express-graphql 来构建 GraphQL API,你可能会遇到一些问题,特别是当你尝试将对象数组从突变中返回时。
在这篇文章中,我们将学习如何解决这个问题,以便你在开发中更加高效。
当你尝试从突变中返回对象数组时,你可能会遇到以下问题:
mutation {
createUsers(users: [{name: "Alice"}, {name: "Bob"}]) {
id
name
}
}
如果你的突变中返回的是一个单独的用户对象,那么这个突变可能会成功。但是,如果你尝试返回多个用户对象,你可能会得到以下错误:
{
"errors": [
{
"message": "Expected Iterable, but did not find one for field \"createUsers\".",
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"stacktrace": [
"Error: Expected Iterable, but did not find one for field \"createUsers\".↵ at new GraphQLError (/app/node_modules/graphql/error/GraphQLError.js:117:24)",
"..."
]
}
}
}
]
}
这个错误的原因是,GraphQL 突变返回的类型必须是 Iterable 类型,而对象数组并不是 Iterable 类型。
为了解决这个问题,我们需要将对象数组转换为可迭代的类型。
首先,在你的突变的返回类型中,你需要使用包装类型 GraphQLList
:
const UserType = new GraphQLObjectType({
name: 'User',
fields: () => ({
id: { type: GraphQLID },
name: { type: GraphQLString },
}),
});
const createUserMutation: GraphQLFieldConfig<any, any> = {
type: new GraphQLList(UserType),
args: {
users: { type: new GraphQLList(new GraphQLInputObjectType({
name: 'UserInput',
fields: () => ({
name: { type: GraphQLString },
}),
})) },
},
resolve: async (_, { users }) => {
// 注意:这里返回的是一个可迭代的对象
const createdUsers = await Promise.all(
users.map(async ({ name }) => {
return await createUser(name);
})
);
return createdUsers;
},
};
注意,在 createUserMutation
的 resolve
方法中,我们使用了 Promise.all
来等待所有创建用户的 Promise 解决,并返回一个可迭代的对象。
接下来,在你的 GraphQLSchema
中声明该突变:
const schema = new GraphQLSchema({
query: RootQuery,
mutation: new GraphQLObjectType({
name: 'Mutation',
fields: {
createUser: createUserMutation,
},
}),
});
现在,当你尝试使用突变来创建多个用户时,你应该能够正确地返回对象数组了。
在本文中,我们解决了 GraphQL 突变未在 express-graphql 中显示对象数组的问题。我们学习了如何使用包装类型 GraphQLList
来解决这个问题,并在 resolve
方法中返回一个可迭代的对象。现在,你可以在自己的项目中实现多个对象的创建突变。