optics-agent 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/LICENSE +21 -0
- data/README.md +139 -0
- data/lib/apollo/optics/proto/reports_pb.rb +145 -0
- data/lib/optics-agent.rb +4 -0
- data/lib/optics-agent/agent.rb +56 -0
- data/lib/optics-agent/graphql-middleware.rb +18 -0
- data/lib/optics-agent/instrumentation/introspection-query.graphql +91 -0
- data/lib/optics-agent/instrumentation/query-schema.rb +9 -0
- data/lib/optics-agent/normalization/latency.rb +14 -0
- data/lib/optics-agent/normalization/query.rb +156 -0
- data/lib/optics-agent/rack-middleware.rb +43 -0
- data/lib/optics-agent/reporting/helpers.rb +32 -0
- data/lib/optics-agent/reporting/query-trace.rb +54 -0
- data/lib/optics-agent/reporting/query.rb +65 -0
- data/lib/optics-agent/reporting/report.rb +102 -0
- data/lib/optics-agent/reporting/report_job.rb +24 -0
- data/lib/optics-agent/reporting/schema.rb +56 -0
- data/lib/optics-agent/reporting/schema_job.rb +14 -0
- data/lib/optics-agent/reporting/send-message.rb +23 -0
- data/spec/graphql-middleware_spec.rb +46 -0
- data/spec/latency_spec.rb +34 -0
- data/spec/query-normalization_spec.rb +105 -0
- data/spec/query_trace_spec.rb +43 -0
- data/spec/report_spec.rb +194 -0
- data/spec/schema-introspection_spec.rb +27 -0
- data/spec/schema_spec.rb +33 -0
- data/spec/spec_helper.rb +103 -0
- metadata +148 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NDY0NThhZDNkNTNhNGYwOWEyMmFlMDhjOGFkNGVlNjM0MjAzYWNkNw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
YWIzNWIxMzNhMGRkMTA3ZGZjMWRiODNjYWVmNTY3OTY4ODA1ZmIxNg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Yzk3ODZjY2UzNWRlMzExMGEyMmY1MmRmNDBhNDA3MzVkYzg4ZjRkMWY1NTU3
|
10
|
+
ZjUwNzU1OWJhNjVhOGQ0OTYxZTk0YmQ0NWMzMDdmYzM4N2M3ZTdmMDQyMDMx
|
11
|
+
NWUyMDY4NmE1ODVlYjk1MWM4ZDY2MzY0Y2U1ZTM3ODljMzIzY2Q=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
NGVlZGUyNTRmM2E3OGRjMWE1MGJkNmQ4ODQ2MjQ3MWIxOTY1YWM0ZDI1NDJi
|
14
|
+
NzUzYTk2MTc4ZDNmNzJmZDdkZjFiOWZmNDM2MzQwOGZhYzM4ZjExZWFkYjM3
|
15
|
+
ZmUxZjM0NDZkYjJmMDc2ODFiMjUyMTI2M2NiYzY5ZGY5MmFiOWM=
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2016 Meteor Development Group, Inc.
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,139 @@
|
|
1
|
+
# optics-agent-ruby
|
2
|
+
Optics Agent for GraphQL Monitoring in Ruby.
|
3
|
+
|
4
|
+
This is an alpha release, suitable for use in development contexts. There are still some outstanding improvements to make it ready for production contexts; see the [known limitations](#known-limitations) section below.
|
5
|
+
|
6
|
+
[](https://travis-ci.org/apollostack/optics-agent-ruby)
|
7
|
+
|
8
|
+
## Installing
|
9
|
+
|
10
|
+
Add
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'optics-agent'
|
14
|
+
```
|
15
|
+
|
16
|
+
To your `Gemfile`
|
17
|
+
|
18
|
+
## Setup
|
19
|
+
|
20
|
+
### API key
|
21
|
+
|
22
|
+
You'll need to run your app with the `OPTICS_API_KEY` environment variable set to the name of your Apollo Optics service; at the moment Optics is in early access alpha--[get in touch](http://www.apollostack.com/optics) if you want to be part of our early access program.
|
23
|
+
|
24
|
+
### Basic Rack/Sinatra
|
25
|
+
|
26
|
+
Create an agent
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
# we expect one day there'll be some options
|
30
|
+
agent = OpticsAgent::Agent.instance
|
31
|
+
```
|
32
|
+
|
33
|
+
Register the Rack middleware (say in a `config.ru`):
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
use agent.rack_middleware
|
37
|
+
```
|
38
|
+
|
39
|
+
Register the Graphql middleware:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
agent.instrument_schema(YourSchema)
|
43
|
+
```
|
44
|
+
|
45
|
+
Add something like this to your route:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
post '/graphql' do
|
49
|
+
request.body.rewind
|
50
|
+
document = JSON.parse request.body.read
|
51
|
+
result = Schema.execute(document["query"],
|
52
|
+
variables: document["variables"],
|
53
|
+
context: { optics_agent: env[:optics_agent].with_document(document) }
|
54
|
+
)
|
55
|
+
JSON.generate(result)
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
## Rails
|
60
|
+
|
61
|
+
The equivalent of the above for Rails is (I welcome better solutions!)
|
62
|
+
|
63
|
+
Create an agent in `config/apllication.rb`, and register the rack middleware:
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
module XXXRails
|
67
|
+
class Application < Rails::Application
|
68
|
+
# ...
|
69
|
+
|
70
|
+
config.optics_agent = OpticsAgent::Agent.instance
|
71
|
+
config.middleware.use config.optics_agent.rack_middleware
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
```
|
76
|
+
|
77
|
+
Register the Graphql middleware when you create your schema:
|
78
|
+
|
79
|
+
```ruby
|
80
|
+
Rails.application.config.optics_agent.instrument_schema(YourSchema)
|
81
|
+
```
|
82
|
+
|
83
|
+
Add something like this to your `graphql` action:
|
84
|
+
|
85
|
+
```ruby
|
86
|
+
def create
|
87
|
+
query_string = params[:query]
|
88
|
+
query_variables = ensure_hash(params[:variables])
|
89
|
+
result = YourSchema.execute(query_string,
|
90
|
+
variables: query_variables,
|
91
|
+
context: {
|
92
|
+
optics_agent: env[:optics_agent].with_document(params)
|
93
|
+
}
|
94
|
+
)
|
95
|
+
render json: result
|
96
|
+
end
|
97
|
+
```
|
98
|
+
|
99
|
+
You can check out the GitHunt Rails API server example here: https://github.com/apollostack/githunt-api-rails
|
100
|
+
|
101
|
+
## Known limitations
|
102
|
+
|
103
|
+
Currently the agent is in alpha state; it is intended for early access use in development or basic (non-performance oriented) staging testing.
|
104
|
+
|
105
|
+
We are working on resolving a [list of issues](https://github.com/apollostack/optics-agent-ruby/projects/1) to put together a production-ready beta launch. The headline issues as things stand are:
|
106
|
+
|
107
|
+
- The agent is overly chatty and uses a naive threading mechanism that may lose reporting data when threads exit/etc.
|
108
|
+
- Instrumentation timings may not be correct in all uses cases, and query times include the full rack request time.
|
109
|
+
|
110
|
+
You can follow along with our [Beta Release Project](https://github.com/apollostack/optics-agent-ruby/projects/1), or even get in touch if you want to help out getting there!
|
111
|
+
|
112
|
+
## Development
|
113
|
+
|
114
|
+
### Running tests
|
115
|
+
|
116
|
+
```
|
117
|
+
bundle install
|
118
|
+
bundle exec rspec
|
119
|
+
```
|
120
|
+
|
121
|
+
### Building protobuf definitions
|
122
|
+
|
123
|
+
Ensure you've installed `protobuf` and development dependencies.
|
124
|
+
|
125
|
+
```bash
|
126
|
+
# this works on OSX
|
127
|
+
brew install protobuf
|
128
|
+
|
129
|
+
# ensure it's version 3
|
130
|
+
protoc --version
|
131
|
+
|
132
|
+
bundle install
|
133
|
+
````
|
134
|
+
|
135
|
+
Compile the `.proto` definitions with
|
136
|
+
|
137
|
+
```bash
|
138
|
+
bundle exec rake proto:compile
|
139
|
+
```
|
@@ -0,0 +1,145 @@
|
|
1
|
+
# Generated by the protocol buffer compiler. DO NOT EDIT!
|
2
|
+
# source: reports.proto
|
3
|
+
|
4
|
+
require 'google/protobuf'
|
5
|
+
|
6
|
+
Google::Protobuf::DescriptorPool.generated_pool.build do
|
7
|
+
add_message "apollo.optics.proto.Id128" do
|
8
|
+
optional :high, :sfixed64, 1
|
9
|
+
optional :low, :sfixed64, 2
|
10
|
+
end
|
11
|
+
add_message "apollo.optics.proto.Timestamp" do
|
12
|
+
optional :seconds, :int64, 1
|
13
|
+
optional :nanos, :int32, 2
|
14
|
+
end
|
15
|
+
add_message "apollo.optics.proto.Error" do
|
16
|
+
optional :message, :string, 1
|
17
|
+
end
|
18
|
+
add_message "apollo.optics.proto.Trace" do
|
19
|
+
optional :server_id, :message, 1, "apollo.optics.proto.Id128"
|
20
|
+
optional :client_id, :message, 2, "apollo.optics.proto.Id128"
|
21
|
+
optional :start_time, :message, 4, "apollo.optics.proto.Timestamp"
|
22
|
+
optional :signature, :string, 5
|
23
|
+
optional :details, :message, 6, "apollo.optics.proto.Trace.Details"
|
24
|
+
optional :client_name, :string, 7
|
25
|
+
optional :client_version, :string, 8
|
26
|
+
optional :client_address, :string, 9
|
27
|
+
optional :http, :message, 10, "apollo.optics.proto.Trace.HTTPInfo"
|
28
|
+
optional :parse, :message, 12, "apollo.optics.proto.Trace.Node"
|
29
|
+
optional :validate, :message, 13, "apollo.optics.proto.Trace.Node"
|
30
|
+
optional :execute, :message, 14, "apollo.optics.proto.Trace.Node"
|
31
|
+
end
|
32
|
+
add_message "apollo.optics.proto.Trace.Details" do
|
33
|
+
map :variables, :string, :bytes, 1
|
34
|
+
optional :raw_query, :string, 2
|
35
|
+
optional :operation_name, :string, 3
|
36
|
+
end
|
37
|
+
add_message "apollo.optics.proto.Trace.HTTPInfo" do
|
38
|
+
optional :method, :enum, 1, "apollo.optics.proto.Trace.HTTPInfo.Method"
|
39
|
+
optional :host, :string, 2
|
40
|
+
optional :path, :string, 3
|
41
|
+
map :headers, :string, :string, 4
|
42
|
+
optional :secure, :bool, 8
|
43
|
+
optional :protocol, :string, 9
|
44
|
+
end
|
45
|
+
add_enum "apollo.optics.proto.Trace.HTTPInfo.Method" do
|
46
|
+
value :UNKNOWN, 0
|
47
|
+
value :OPTIONS, 1
|
48
|
+
value :GET, 2
|
49
|
+
value :HEAD, 3
|
50
|
+
value :POST, 4
|
51
|
+
value :PUT, 5
|
52
|
+
value :DELETE, 6
|
53
|
+
value :TRACE, 7
|
54
|
+
value :CONNECT, 8
|
55
|
+
value :PATCH, 9
|
56
|
+
end
|
57
|
+
add_message "apollo.optics.proto.Trace.Node" do
|
58
|
+
optional :type, :string, 3
|
59
|
+
optional :alias, :string, 4
|
60
|
+
optional :start_time, :uint64, 8
|
61
|
+
optional :end_time, :uint64, 9
|
62
|
+
repeated :error, :message, 11, "apollo.optics.proto.Error"
|
63
|
+
repeated :child, :message, 12, "apollo.optics.proto.Trace.Node"
|
64
|
+
oneof :id do
|
65
|
+
optional :field_name, :string, 1
|
66
|
+
optional :index, :uint32, 2
|
67
|
+
end
|
68
|
+
end
|
69
|
+
add_message "apollo.optics.proto.ReportHeader" do
|
70
|
+
optional :service, :string, 3
|
71
|
+
optional :hostname, :string, 5
|
72
|
+
optional :agent_version, :string, 6
|
73
|
+
optional :service_version, :string, 7
|
74
|
+
optional :runtime_version, :string, 8
|
75
|
+
optional :uname, :string, 9
|
76
|
+
end
|
77
|
+
add_message "apollo.optics.proto.StatsPerClientName" do
|
78
|
+
repeated :latency_count, :uint64, 1
|
79
|
+
repeated :error_count, :uint64, 2
|
80
|
+
map :count_per_version, :string, :uint64, 3
|
81
|
+
end
|
82
|
+
add_message "apollo.optics.proto.FieldStat" do
|
83
|
+
optional :name, :string, 2
|
84
|
+
optional :returnType, :string, 3
|
85
|
+
repeated :latency_count, :uint64, 8
|
86
|
+
end
|
87
|
+
add_message "apollo.optics.proto.TypeStat" do
|
88
|
+
optional :name, :string, 1
|
89
|
+
repeated :field, :message, 2, "apollo.optics.proto.FieldStat"
|
90
|
+
end
|
91
|
+
add_message "apollo.optics.proto.StatsPerSignature" do
|
92
|
+
map :per_client_name, :string, :message, 1, "apollo.optics.proto.StatsPerClientName"
|
93
|
+
repeated :per_type, :message, 2, "apollo.optics.proto.TypeStat"
|
94
|
+
end
|
95
|
+
add_message "apollo.optics.proto.TracesReport" do
|
96
|
+
optional :header, :message, 1, "apollo.optics.proto.ReportHeader"
|
97
|
+
repeated :trace, :message, 2, "apollo.optics.proto.Trace"
|
98
|
+
end
|
99
|
+
add_message "apollo.optics.proto.Field" do
|
100
|
+
optional :name, :string, 2
|
101
|
+
optional :returnType, :string, 3
|
102
|
+
end
|
103
|
+
add_message "apollo.optics.proto.Type" do
|
104
|
+
optional :name, :string, 1
|
105
|
+
repeated :field, :message, 2, "apollo.optics.proto.Field"
|
106
|
+
end
|
107
|
+
add_message "apollo.optics.proto.StatsReport" do
|
108
|
+
optional :header, :message, 1, "apollo.optics.proto.ReportHeader"
|
109
|
+
optional :start_time, :message, 8, "apollo.optics.proto.Timestamp"
|
110
|
+
optional :end_time, :message, 9, "apollo.optics.proto.Timestamp"
|
111
|
+
optional :realtime_duration, :uint64, 10
|
112
|
+
map :per_signature, :string, :message, 12, "apollo.optics.proto.StatsPerSignature"
|
113
|
+
repeated :type, :message, 13, "apollo.optics.proto.Type"
|
114
|
+
end
|
115
|
+
add_message "apollo.optics.proto.SchemaReport" do
|
116
|
+
optional :header, :message, 1, "apollo.optics.proto.ReportHeader"
|
117
|
+
optional :introspection_result, :string, 8
|
118
|
+
repeated :type, :message, 9, "apollo.optics.proto.Type"
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
module Apollo
|
123
|
+
module Optics
|
124
|
+
module Proto
|
125
|
+
Id128 = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Id128").msgclass
|
126
|
+
Timestamp = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Timestamp").msgclass
|
127
|
+
Error = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Error").msgclass
|
128
|
+
Trace = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Trace").msgclass
|
129
|
+
Trace::Details = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Trace.Details").msgclass
|
130
|
+
Trace::HTTPInfo = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Trace.HTTPInfo").msgclass
|
131
|
+
Trace::HTTPInfo::Method = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Trace.HTTPInfo.Method").enummodule
|
132
|
+
Trace::Node = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Trace.Node").msgclass
|
133
|
+
ReportHeader = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.ReportHeader").msgclass
|
134
|
+
StatsPerClientName = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.StatsPerClientName").msgclass
|
135
|
+
FieldStat = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.FieldStat").msgclass
|
136
|
+
TypeStat = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.TypeStat").msgclass
|
137
|
+
StatsPerSignature = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.StatsPerSignature").msgclass
|
138
|
+
TracesReport = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.TracesReport").msgclass
|
139
|
+
Field = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Field").msgclass
|
140
|
+
Type = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.Type").msgclass
|
141
|
+
StatsReport = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.StatsReport").msgclass
|
142
|
+
SchemaReport = Google::Protobuf::DescriptorPool.generated_pool.lookup("apollo.optics.proto.SchemaReport").msgclass
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/optics-agent.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'singleton'
|
2
|
+
require 'optics-agent/rack-middleware'
|
3
|
+
require 'optics-agent/graphql-middleware'
|
4
|
+
require 'optics-agent/reporting/report_job'
|
5
|
+
require 'optics-agent/reporting/schema_job'
|
6
|
+
require 'optics-agent/reporting/query-trace'
|
7
|
+
|
8
|
+
module OpticsAgent
|
9
|
+
# XXX: this is a class but acts as a singleton right now.
|
10
|
+
# Need to figure out how to pass the agent into the middleware
|
11
|
+
# (for instance we could dynamically generate a middleware class,
|
12
|
+
# or ask the user to pass the agent as an option) to avoid it
|
13
|
+
class Agent
|
14
|
+
include Singleton
|
15
|
+
include OpticsAgent::Reporting
|
16
|
+
|
17
|
+
attr_reader :schema
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@query_queue = []
|
21
|
+
@semaphone = Mutex.new
|
22
|
+
ReportJob.perform_in(60, self)
|
23
|
+
end
|
24
|
+
|
25
|
+
def instrument_schema(schema)
|
26
|
+
@schema = schema
|
27
|
+
schema.middleware << graphql_middleware
|
28
|
+
|
29
|
+
puts 'scheduling schema job'
|
30
|
+
SchemaJob.perform_in(10, self)
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_query(query, rack_env, start_time, end_time)
|
34
|
+
@semaphone.synchronize {
|
35
|
+
@query_queue << [query, rack_env, start_time, end_time]
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
def clear_query_queue
|
40
|
+
@semaphone.synchronize {
|
41
|
+
queue = @query_queue
|
42
|
+
@query_queue = []
|
43
|
+
queue
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
def rack_middleware
|
48
|
+
OpticsAgent::RackMiddleware
|
49
|
+
end
|
50
|
+
|
51
|
+
def graphql_middleware
|
52
|
+
# graphql middleware doesn't seem to need the agent but certainly could have it
|
53
|
+
OpticsAgent::GraphqlMiddleware.new
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module OpticsAgent
|
2
|
+
class GraphqlMiddleware
|
3
|
+
def call(parent_type, parent_object, field_definition, field_args, query_context, next_middleware)
|
4
|
+
# This happens when an introspection query occurs (reporting schema)
|
5
|
+
# However, we could also use it to tell people if they've set things up wrong.
|
6
|
+
return next_middleware.call unless query_context[:optics_agent]
|
7
|
+
|
8
|
+
start_time = Time.now
|
9
|
+
result = next_middleware.call
|
10
|
+
end_time = Time.now
|
11
|
+
|
12
|
+
query = query_context[:optics_agent][:query]
|
13
|
+
query.report_field(parent_type.to_s, field_definition.name, start_time, end_time)
|
14
|
+
|
15
|
+
result
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
query ShorterIntrospectionQuery {
|
2
|
+
__schema {
|
3
|
+
queryType { name }
|
4
|
+
mutationType { name }
|
5
|
+
subscriptionType { name }
|
6
|
+
types {
|
7
|
+
...FullType
|
8
|
+
}
|
9
|
+
directives {
|
10
|
+
name
|
11
|
+
# description
|
12
|
+
locations
|
13
|
+
args {
|
14
|
+
...InputValue
|
15
|
+
}
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
fragment FullType on __Type {
|
21
|
+
kind
|
22
|
+
name
|
23
|
+
# description
|
24
|
+
fields(includeDeprecated: true) {
|
25
|
+
name
|
26
|
+
# description
|
27
|
+
args {
|
28
|
+
...InputValue
|
29
|
+
}
|
30
|
+
type {
|
31
|
+
...TypeRef
|
32
|
+
}
|
33
|
+
isDeprecated
|
34
|
+
# deprecationReason
|
35
|
+
}
|
36
|
+
inputFields {
|
37
|
+
...InputValue
|
38
|
+
}
|
39
|
+
interfaces {
|
40
|
+
...TypeRef
|
41
|
+
}
|
42
|
+
enumValues(includeDeprecated: true) {
|
43
|
+
name
|
44
|
+
# description
|
45
|
+
isDeprecated
|
46
|
+
# deprecationReason
|
47
|
+
}
|
48
|
+
possibleTypes {
|
49
|
+
...TypeRef
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
fragment InputValue on __InputValue {
|
54
|
+
name
|
55
|
+
# description
|
56
|
+
type { ...TypeRef }
|
57
|
+
# defaultValue
|
58
|
+
}
|
59
|
+
|
60
|
+
fragment TypeRef on __Type {
|
61
|
+
kind
|
62
|
+
name
|
63
|
+
ofType {
|
64
|
+
kind
|
65
|
+
name
|
66
|
+
ofType {
|
67
|
+
kind
|
68
|
+
name
|
69
|
+
ofType {
|
70
|
+
kind
|
71
|
+
name
|
72
|
+
ofType {
|
73
|
+
kind
|
74
|
+
name
|
75
|
+
ofType {
|
76
|
+
kind
|
77
|
+
name
|
78
|
+
ofType {
|
79
|
+
kind
|
80
|
+
name
|
81
|
+
ofType {
|
82
|
+
kind
|
83
|
+
name
|
84
|
+
}
|
85
|
+
}
|
86
|
+
}
|
87
|
+
}
|
88
|
+
}
|
89
|
+
}
|
90
|
+
}
|
91
|
+
}
|