Directives in Rails GraphQL allow you to modify the behavior of fields, types, and other schema elements. Custom directives work as event listeners and triggers, enabling powerful runtime modifications to your GraphQL operations.
Define arguments for your directive using the argument method:
class CachedDirective < Rails::GraphQL::Directive placed_on :query argument :id, :ID, null: false, desc: 'The unique identifier of the cached operation.' argument :ttl, :int, default: 3600, desc: 'Time to live in seconds'end
class DeprecatedDirective < Rails::GraphQL::Directive placed_on :field_definition, :enum_value argument :reason, :string on(:finalize, for: Type::Enum) do |event| return unless event.current_value.deprecated? value = event.current_value.to_s item = "#{value} value for the #{event.source.gql_name} field" event.request.report_error(build_message(item)) end private def build_message(item) result = "The #{item} is deprecated" result << ", reason: #{args.reason}" if args.reason.present? result << '.' endend
module GraphQL class RateLimitDirective < Rails::GraphQL::Directive placed_on :field_definition desc 'Limits the rate at which a field can be accessed' argument :max_calls, :int, null: false, desc: 'Maximum calls per window' argument :window, :int, default: 60, desc: 'Time window in seconds' on(:organized) do |event| key = "rate_limit:#{event.request.context[:user_id]}:#{event.field.gql_name}" count = Rails.cache.increment(key, 1, expires_in: args.window.seconds) if count > args.max_calls event.request.report_error( "Rate limit exceeded. Max #{args.max_calls} calls per #{args.window} seconds." ) end end endend
module GraphQL class AuthDirective < Rails::GraphQL::Directive placed_on :field_definition, :object desc 'Requires authentication to access the field' argument :role, :string, desc: 'Required user role' on(:authorize) do |event| user = event.request.context[:current_user] unless user.present? raise GraphQL::ExecutionError, 'Authentication required' end if args.role.present? && !user.has_role?(args.role) raise GraphQL::ExecutionError, "Required role: #{args.role}" end end endend
on(:organized) do |event| # Access directive arguments args.my_argument # Access the field event.field.gql_name # Access the request event.request.context[:current_user] # Access the source type event.source.gql_name # Report errors event.request.report_error('Error message')end