Fields (and their arguments, and input object arguments) can be validated at runtime using built-in or custom validators.

Validations are configured in field(...) or argument(...) calls:

argument :home_phone, String,
  description: "A US phone number",
  validates: { format: { with: /\d{3}-\d{3}-\d{4}/ } }


field :comments, [Comment],
  description: "Find comments by author ID or author name" do
  argument :author_id, ID, required: false
  argument :author_name, String, required: false
  # Either `authorId` or `authorName` must be provided by the client, but not both:
  validates required: { one_of: [:author_id, :author_name] }

Validations can be provided with a keyword (validates: { ... }) or with a method inside the configuration block (validates ...).

Built-In Validations

See each validator’s API docs for details:

Some of the validators accept customizable messages for certain validation failures; see the API docs for examples.

allow_blank: and allow_null: may affect other validations, for example:

validates: { format: { with: /\A\d{4}\Z/ }, allow_blank: true }

Will permit any String containing four digits, or the empty string ("") if Rails is loaded. (GraphQL-Ruby checks for .blank?, which is usually defined by Rails.)

Alternatively, they can be used alone, for example:

argument :id, ID, required: false, validates: { allow_null: true }

Will reject any query that passes id: null.

Custom Validators

You can write custom validators, too. A validator is a class that extends GraphQL::Schema::Validator. It should implement:

Then, custom validators can be attached either:

Validators are initialized when the schema is constructed (at application boot), and validate(...) is called while executing the query. There’s one Validator instance for each configuration on each field, argument, or input object. (Validator instances aren’t shared.)