GraphQL Code First模式下如何定义数组参数实现批量创建用户
GraphQL Code First模式下批量创建接口复用单接口参数实现方案
错误原因
GraphQL字段的args配置规则为键值对对象结构,格式固定为{ 参数名: { type: 对应GraphQL类型 } },直接将参数定义包裹为数组传给args不符合语法规范,无法被GraphQL解析。
批量创建的参数逻辑是定义一个数组类型的入参,而非将整个args配置改为数组。
实现方式
根据是否需要兼容原有createUser接口的调用逻辑,可选两种方案:
- 方案1:兼容原有平铺参数写法,不需要调整已有
createUser的调用方 - 方案2:统一输入结构,适合长期维护的项目,复用性更高
方案1:兼容原有接口调用
先抽离单用户创建的公共字段配置,两个接口直接复用,无需调整原有createUser的传参方式:
// 抽离公共字段配置,两处接口共用 const commonUserCreateFields = { email: { type: GraphQLString }, username: { type: GraphQLString }, firstName: { type: GraphQLString }, lastName: { type: GraphQLString } } export const createUser = { type: userType, args: commonUserCreateFields, // 保持原有平铺参数逻辑,调用方无感知 resolve: async (_, args, { userAuth }) => { try { const user = await db.models.userModel.create(args); return user; } catch (error) { throw new Error(error.message) } } } export const createManyUser = { type: new GraphQLList(userType), args: { // 定义名为userList的入参,类型为单用户结构组成的数组 userList: { type: new GraphQLList( new GraphQLInputObjectType({ name: 'CreateUserPayload', fields: commonUserCreateFields }) ) } }, resolve: async (_, args, { userAuth }) => { try { // 从args中取定义好的userList参数传给bulkCreate,不要直接传整个args const res = await db.models.userModel.bulkCreate(args.userList); return res; } catch (error) { throw new Error(error.message) } } }
方案2:统一输入类型规范(推荐)
明确定义可复用的用户创建输入对象类型,所有相关接口直接引用,结构更清晰:
// 全局定义可复用的创建用户输入类型 const CreateUserInput = new GraphQLInputObjectType({ name: 'CreateUserInput', fields: { email: { type: GraphQLString }, username: { type: GraphQLString }, firstName: { type: GraphQLString }, lastName: { type: GraphQLString } } }) export const createUser = { type: userType, args: { userInfo: { type: CreateUserInput } }, resolve: async (_, args, { userAuth }) => { try { const user = await db.models.userModel.create(args.userInfo); return user; } catch (error) { throw new Error(error.message) } } } export const createManyUser = { type: new GraphQLList(userType), args: { userList: { type: new GraphQLList(CreateUserInput) } }, resolve: async (_, args, { userAuth }) => { try { const res = await db.models.userModel.bulkCreate(args.userList); return res; } catch (error) { throw new Error(error.message) } } }
避坑提示
- 所有对象/数组结构的自定义入参,必须通过
GraphQLInputObjectType定义输入类型,不能直接传入普通JS对象作为类型配置 - resolve中读取参数时,必须和
args里定义的参数名对应,禁止直接将整个args对象传给ORM操作方法 - 标量类型需使用GraphQL内置类型(如
GraphQLString),不要直接传入JS原生String构造函数,避免原生graphql-js抛出类型错误
内容的提问来源于stack exchange,提问作者Maher Aldous
相关产品推荐
相关产品推荐

