Overview
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.Basic Directive Structure
Create a custom directive by inheriting fromRails::GraphQL::Directive:
Directive Locations
Directives can be placed on specific schema locations usingplaced_on:
Execution Locations
:query- Query operations:mutation- Mutation operations:subscription- Subscription operations:field- Field selections:fragment_definition- Fragment definitions:fragment_spread- Fragment spreads:inline_fragment- Inline fragments
Definition Locations
:schema- Schema definition:scalar- Scalar types:object- Object types:field_definition- Field definitions:argument_definition- Argument definitions:interface- Interface types:union- Union types:enum- Enum types:enum_value- Enum values:input_object- Input object types:input_field_definition- Input field definitions
Directive Arguments
Define arguments for your directive using theargument method:
Event Listeners
Directives can listen to lifecycle events using theon method:
Available Events
:attach- When the directive is attached to an element:authorize- During authorization checks:organized- After field organization:prepared- After preparation phase:finalize- During finalization:query- Query execution:mutation- Mutation execution:subscription- Subscription execution
Basic Event Handler
Event Filters
Use event filters to conditionally execute directive logic:The for Filter
Target specific types:
The on Filter
Filter by the event target:
The during Filter
Filter by execution phase:
Real-World Examples
Rate Limiting Directive
Authentication Directive
Logging Directive
Repeatable Directives
Mark a directive as repeatable to allow multiple instances:Using Directives
On Fields
On Enum Values
Shortcut Syntax
Accessing Directive Data
Inside directive event handlers:Best Practices
Keep Directives Focused
Keep Directives Focused
Each directive should have a single, well-defined purpose. Don’t create directives that do too many things.
Use Appropriate Event Listeners
Use Appropriate Event Listeners
Choose the right lifecycle event for your directive logic. Use
:authorize for authentication, :organized for validation, and :finalize for cleanup.Handle Errors Gracefully
Handle Errors Gracefully
Always provide clear error messages when directive validation fails. Use
event.request.report_error for user-facing errors.Document Your Directives
Document Your Directives
Use the
desc method to provide clear documentation about what your directive does and how to use it.Next Steps
Custom Scalars
Learn how to create custom scalar types
Advanced Types
Explore advanced type system features