Skip to content

Commit

Permalink
Document custom directives
Browse files Browse the repository at this point in the history
  • Loading branch information
rmosolgo committed Jan 29, 2019
1 parent 07163cf commit ed20cda
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
1 change: 1 addition & 0 deletions guides/css/main.scss
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,7 @@ a:hover, a:hover code {
color: $color;
border-radius: $code-border-radius;
padding: 10px 10px 0px 10px;
margin-bottom: 10px;
border: 1px solid $color;
a {
color: $color;
Expand Down
80 changes: 80 additions & 0 deletions guides/type_definitions/directives.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
layout: guide
doc_stub: false
search: true
section: Type Definitions
title: Directives
desc: Special instructions for the GraphQL runtime
index: 10
class_based_api: true
experimental: true
---


Directives are system-defined keywords that modify execution. All GraphQL systems have at least _two_ directives, `@skip` and `@include`. For example:

```ruby
query ProfileView($renderingDetailedProfile: Boolean!){
viewer {
handle
# These fields will be included only if the check passes:
... @include(if: $renderingDetailedProfile) {
location
homepageUrl
}
}
}
```

Here's how the two built-in directives work:

- `@skip(if: ...)` skips the selection if the `if: ...` value is truthy ({{ "GraphQL::Schema::Directive::Skip" | api_doc }})
- `@include(if: ...)` includes the selection if the `if: ...` value is truthy ({{ "GraphQL::Schema::Directive::Include" | api_doc }})

GraphQL-Ruby also supports custom directives for use with the {% internal_link "interpreter runtime", "/queries/interpreter" %}.

## Custom Directives

Custom directives extend {{ "GraphQL::Schema::Directive" | api_doc }}:

```ruby
# app/graphql/directives/my_directive.rb
class Directives::MyDirective < GraphQL::Schema::Directive
description "A nice runtime customization"
end
```

Then, they're hooked up to the schema using `directive(...)`:

```ruby
class MySchema < GraphQL::Schema
# Custom directives are only supported by the Interpreter runtime
use GraphQL::Execution::Interpreter
# Attach the custom directive to the schema
directive(Directives::MyDirective)
end
```

{{ "GraphQL::Schema::Directive::Feature" | api_doc }} and {{ "GraphQL::Schema::Directive::Transform" | api_doc }} are included in the library as examples.

### Arguments

Like fields, directives may have {% internal_link "arguments", "/fields/arguments" %} :

```ruby
argument :if, Boolean, required: true,
description: "Skips the selection if this condition is true"
```

### Runtime hooks

Directive classes may implement the following class methods to interact with the runtime:

- `def self.include?(obj, args, ctx)`: If this hook returns `false`, the nodes flagged by this directive will be skipped at runtime.
- `def self.resolve(obj, args, ctx)`: Wraps the resolution of flagged nodes. Resolution is passed as a __block__, so `yield` will continue resolution. The return value of this method will be treated as the return value of the flagged field.

Looking for a runtime hook that isn't listed here? {% open_an_issue "New directive hook: @something", "<!-- Describe how the directive would be used and then how you might implement it --> " %} to start the conversation!

### Directive object lifecycle

Currently, Directive classes are never initialized. A later version of GraphQL may initialize these objects for runtime application.

0 comments on commit ed20cda

Please sign in to comment.