Skip to content

Commit d0f012f

Browse files
committed
doc(Schema) add instrumentation guide
1 parent 456de26 commit d0f012f

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed

guides/schema/instrumentation.md

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
---
2+
title: Schema — Instrumentation
3+
---
4+
5+
Instrumentation provides hooks for inserting custom code around field resolution and query execution.
6+
7+
## Field Instrumentation
8+
9+
Field instrumentation can be attached during schema definition:
10+
11+
```ruby
12+
MySchema = GraphQL::Schema.define do
13+
instrument(:field, MyFieldInstrumentation.new)
14+
end
15+
```
16+
17+
The instrumenter is an object which responds to `#instrument(type, field)`. `#instrument` should return a `GraphQL::Field` instance which will be used during query execution. `#instrument` is called with each type-field pair for _all_ Object types and Interface types in your schema.
18+
19+
Here's an example field instrumenter:
20+
21+
```ruby
22+
class MyFieldInstrumentation
23+
# If a field was flagged to be timed,
24+
# wrap its resolve proc with a timer.
25+
def instrument(type, field)
26+
if field.metadata[:timed]
27+
old_resolve_proc = field.resolve_proc
28+
new_resolve_proc = ->(obj, args, ctx) {
29+
Rails.logger.info("#{type.name}.#{field.name} START: #{Time.now.to_i}")
30+
old_resolve_proc.call(obj, args, ctx)
31+
Rails.logger.info("#{type.name}.#{field.name} END: #{Time.now.to_i}")
32+
}
33+
end
34+
end
35+
end
36+
```
37+
38+
It can be attached as shown above. This implementation will _modify_ the underlying `GraphQL::Field` instance... be warned!
39+
40+
## Query Instrumetation
41+
42+
43+
Query instrumentation can be attached during schema definition:
44+
45+
```ruby
46+
MySchema = GraphQL::Schema.define do
47+
instrument(:query, MyQueryInstrumentation.new)
48+
end
49+
```
50+
51+
The instrumenter must implement `#before_query(query)` and `#after_query(query)`. The return value of these methods are not used. They receive the `GraphQL::Query` instance.
52+
53+
```ruby
54+
class MyQueryInstrumentation
55+
# Log the time of the query
56+
def before_query(query)
57+
Rails.logger.info("Query begin: #{Time.now.to_i}")
58+
end
59+
60+
def after_query(query)
61+
Rails.logger.info("Query end: #{Time.now.to_i}")
62+
end
63+
end
64+
```

0 commit comments

Comments
 (0)