Rails GraphQL Mutations如何根据其他参数动态设置字段required必填属性
实现方案说明
GraphQL 本身的类型校验逻辑是静态执行的,在接口声明阶段就已经确定了所有参数的必填规则,无法直接通过给required属性传proc的方式实现依赖其他参数的动态必填校验,你示例中的写法原生 GraphQL Ruby 并不支持,可通过以下两种成熟方案实现需求:
方案1:参数声明为非必填,在resolve方法内做自定义校验
这是最常用的实现方式,修改后代码如下:
class Mutations::CreateAuthor < Mutations::BaseMutation description "Creates Author" argument :name, String, required: false # 原声明的必填改为非必填,移到业务逻辑内校验 argument :email, String, required: false argument :phone, String, required: false field :author, Types::AuthorType, null: false field :errors, [String], null: false def resolve(name:, email:, phone:) # 自定义参数校验逻辑 errors = [] if email.blank? && phone.blank? errors << "邮箱和手机号不能同时为空,至少填写一项" end return {author: nil, errors: errors} if errors.present? author = Author.new(name: name, email: email, phone: phone) if author.save {author: author, errors: []} else {author: nil, errors: author.errors.full_messages} end end end
方案2:用ready?回调做前置校验
如果不想把校验逻辑耦合到resolve方法里,可以用 Mutation 自带的ready?回调在执行业务逻辑前完成参数校验:
class Mutations::CreateAuthor < Mutations::BaseMutation description "Creates Author" argument :name, String, required: false argument :email, String, required: false argument :phone, String, required: false field :author, Types::AuthorType, null: false field :errors, [String], null: false def ready?(**args) if args[:email].blank? && args[:phone].blank? raise GraphQL::ExecutionError, "邮箱和手机号不能同时为空,至少填写一项" end true end def resolve(name:, email:, phone:) author = Author.new(name: name, email: email, phone: phone) if author.save {author: author, errors: []} else {author: nil, errors: author.errors.full_messages} end end end
如果你希望这个动态必填规则能体现在接口文档中,可以在字段描述里明确标注「邮箱、手机号至少填写一项」的规则,方便前端调用方提前知晓校验逻辑。
内容的提问来源于stack exchange,提问作者Hammad Qadeer
相关产品推荐
相关产品推荐

