graphql-stitching 0.0.1 → 0.2.1
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 +4 -4
- data/.github/workflows/ci.yml +8 -2
- data/.gitignore +2 -0
- data/README.md +15 -16
- data/docs/README.md +1 -1
- data/docs/composer.md +45 -4
- data/docs/executor.md +17 -6
- data/docs/images/library.png +0 -0
- data/docs/planner.md +7 -7
- data/docs/request.md +47 -0
- data/docs/supergraph.md +1 -1
- data/graphql-stitching.gemspec +2 -2
- data/lib/graphql/stitching/composer.rb +89 -7
- data/lib/graphql/stitching/executor.rb +49 -28
- data/lib/graphql/stitching/gateway.rb +18 -13
- data/lib/graphql/stitching/planner.rb +17 -11
- data/lib/graphql/stitching/remote_client.rb +4 -4
- data/lib/graphql/stitching/request.rb +133 -0
- data/lib/graphql/stitching/shaper.rb +60 -56
- data/lib/graphql/stitching/supergraph.rb +7 -6
- data/lib/graphql/stitching/util.rb +9 -1
- data/lib/graphql/stitching/version.rb +1 -1
- data/lib/graphql/stitching.rb +5 -1
- metadata +6 -9
- data/.ruby-version +0 -1
- data/Gemfile.lock +0 -49
- data/docs/document.md +0 -15
- data/docs/shaper.md +0 -20
- data/lib/graphql/stitching/document.rb +0 -59
@@ -4,7 +4,7 @@ module GraphQL
|
|
4
4
|
module Stitching
|
5
5
|
class Util
|
6
6
|
|
7
|
-
# gets the named type at the bottom of a non-null/list wrapper
|
7
|
+
# gets the named type at the bottom of a non-null/list wrapper tree
|
8
8
|
def self.get_named_type(type)
|
9
9
|
while type.respond_to?(:of_type)
|
10
10
|
type = type.of_type
|
@@ -12,6 +12,14 @@ module GraphQL
|
|
12
12
|
type
|
13
13
|
end
|
14
14
|
|
15
|
+
# strips non-null wrappers from a type
|
16
|
+
def self.unwrap_non_null(type)
|
17
|
+
while type.is_a?(GraphQL::Schema::NonNull)
|
18
|
+
type = type.of_type
|
19
|
+
end
|
20
|
+
type
|
21
|
+
end
|
22
|
+
|
15
23
|
# gets a deep structural description of a list value type
|
16
24
|
def self.get_list_structure(type)
|
17
25
|
structure = []
|
data/lib/graphql/stitching.rb
CHANGED
@@ -13,6 +13,10 @@ module GraphQL
|
|
13
13
|
end
|
14
14
|
|
15
15
|
attr_writer :stitch_directive
|
16
|
+
|
17
|
+
def stitching_directive_names
|
18
|
+
[stitch_directive]
|
19
|
+
end
|
16
20
|
end
|
17
21
|
end
|
18
22
|
end
|
@@ -20,11 +24,11 @@ end
|
|
20
24
|
require_relative "stitching/gateway"
|
21
25
|
require_relative "stitching/supergraph"
|
22
26
|
require_relative "stitching/composer"
|
23
|
-
require_relative "stitching/document"
|
24
27
|
require_relative "stitching/executor"
|
25
28
|
require_relative "stitching/planner_operation"
|
26
29
|
require_relative "stitching/planner"
|
27
30
|
require_relative "stitching/remote_client"
|
31
|
+
require_relative "stitching/request"
|
28
32
|
require_relative "stitching/shaper"
|
29
33
|
require_relative "stitching/util"
|
30
34
|
require_relative "stitching/version"
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: graphql-stitching
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Greg MacWilliam
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-02-
|
11
|
+
date: 2023-02-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: graphql
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '5.12'
|
69
|
-
description: GraphQL
|
69
|
+
description: Combine GraphQL services into one unified graph
|
70
70
|
email:
|
71
71
|
executables: []
|
72
72
|
extensions: []
|
@@ -74,23 +74,20 @@ extra_rdoc_files: []
|
|
74
74
|
files:
|
75
75
|
- ".github/workflows/ci.yml"
|
76
76
|
- ".gitignore"
|
77
|
-
- ".ruby-version"
|
78
77
|
- Gemfile
|
79
|
-
- Gemfile.lock
|
80
78
|
- LICENSE
|
81
79
|
- Procfile
|
82
80
|
- README.md
|
83
81
|
- Rakefile
|
84
82
|
- docs/README.md
|
85
83
|
- docs/composer.md
|
86
|
-
- docs/document.md
|
87
84
|
- docs/executor.md
|
88
85
|
- docs/gateway.md
|
89
86
|
- docs/images/library.png
|
90
87
|
- docs/images/merging.png
|
91
88
|
- docs/images/stitching.png
|
92
89
|
- docs/planner.md
|
93
|
-
- docs/
|
90
|
+
- docs/request.md
|
94
91
|
- docs/supergraph.md
|
95
92
|
- example/gateway.rb
|
96
93
|
- example/graphiql.html
|
@@ -102,12 +99,12 @@ files:
|
|
102
99
|
- lib/graphql/stitching/composer/base_validator.rb
|
103
100
|
- lib/graphql/stitching/composer/validate_boundaries.rb
|
104
101
|
- lib/graphql/stitching/composer/validate_interfaces.rb
|
105
|
-
- lib/graphql/stitching/document.rb
|
106
102
|
- lib/graphql/stitching/executor.rb
|
107
103
|
- lib/graphql/stitching/gateway.rb
|
108
104
|
- lib/graphql/stitching/planner.rb
|
109
105
|
- lib/graphql/stitching/planner_operation.rb
|
110
106
|
- lib/graphql/stitching/remote_client.rb
|
107
|
+
- lib/graphql/stitching/request.rb
|
111
108
|
- lib/graphql/stitching/shaper.rb
|
112
109
|
- lib/graphql/stitching/supergraph.rb
|
113
110
|
- lib/graphql/stitching/util.rb
|
@@ -128,7 +125,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
125
|
requirements:
|
129
126
|
- - ">="
|
130
127
|
- !ruby/object:Gem::Version
|
131
|
-
version:
|
128
|
+
version: 2.7.0
|
132
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
130
|
requirements:
|
134
131
|
- - ">="
|
data/.ruby-version
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
3.1.1
|
data/Gemfile.lock
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
graphql-stitching (0.0.1)
|
5
|
-
graphql (~> 2.0.16)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
byebug (11.1.3)
|
11
|
-
coderay (1.1.3)
|
12
|
-
foreman (0.87.2)
|
13
|
-
graphql (2.0.16)
|
14
|
-
method_source (1.0.0)
|
15
|
-
minitest (5.17.0)
|
16
|
-
pry (0.14.2)
|
17
|
-
coderay (~> 1.1)
|
18
|
-
method_source (~> 1.0)
|
19
|
-
pry-byebug (3.10.1)
|
20
|
-
byebug (~> 11.0)
|
21
|
-
pry (>= 0.13, < 0.15)
|
22
|
-
rack (3.0.4.1)
|
23
|
-
rackup (2.1.0)
|
24
|
-
rack (>= 3)
|
25
|
-
webrick (~> 1.8)
|
26
|
-
rake (12.3.3)
|
27
|
-
warning (1.3.0)
|
28
|
-
webrick (1.8.1)
|
29
|
-
|
30
|
-
PLATFORMS
|
31
|
-
arm64-darwin-21
|
32
|
-
ruby
|
33
|
-
x86_64-darwin-21
|
34
|
-
x86_64-linux
|
35
|
-
|
36
|
-
DEPENDENCIES
|
37
|
-
bundler (~> 2.0)
|
38
|
-
foreman
|
39
|
-
graphql-stitching!
|
40
|
-
minitest (~> 5.12)
|
41
|
-
pry
|
42
|
-
pry-byebug
|
43
|
-
rack
|
44
|
-
rackup
|
45
|
-
rake (~> 12.0)
|
46
|
-
warning
|
47
|
-
|
48
|
-
BUNDLED WITH
|
49
|
-
2.4.1
|
data/docs/document.md
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
## GraphQL::Stitching::Document
|
2
|
-
|
3
|
-
A `Document` wraps a parsed GraphQL request, and handles the logistics of extracting its appropriate operation, variable definitions, and fragments. A `Document` should be built once for a request and passed through to other stitching components that utilize document information.
|
4
|
-
|
5
|
-
```ruby
|
6
|
-
query = "query FetchMovie($id: ID!) { movie(id:$id) { id genre } }"
|
7
|
-
document = GraphQL::Stitching::Document.new(query, operation_name: "FetchMovie")
|
8
|
-
|
9
|
-
document.ast # parsed AST via GraphQL.parse
|
10
|
-
document.string # normalized printed string
|
11
|
-
document.digest # SHA digest of the normalized string
|
12
|
-
|
13
|
-
document.variables # mapping of variable names to type definitions
|
14
|
-
document.fragments # mapping of fragment names to fragment definitions
|
15
|
-
```
|
data/docs/shaper.md
DELETED
@@ -1,20 +0,0 @@
|
|
1
|
-
## GraphQL::Stitching::Shaper
|
2
|
-
|
3
|
-
The `Shaper` takes the raw output generated by the `GraphQL::Stitching::Executor` and does the final shaping and
|
4
|
-
cleaning. It removes data that was added while building the result, it also handles cleaning up violations that can
|
5
|
-
only occur at the end, such as bubbling up null violoations.
|
6
|
-
|
7
|
-
See the [Executor](./docs/executor.md)
|
8
|
-
|
9
|
-
```ruby
|
10
|
-
raw_result = GraphQL::Stitching::Executor.new(
|
11
|
-
supergraph: supergraph,
|
12
|
-
plan: plan.to_h,
|
13
|
-
variables: variables,
|
14
|
-
).perform(document)
|
15
|
-
|
16
|
-
final_result = GraphQL::Stitching::Shaper.new(
|
17
|
-
supergraph: supergraph,
|
18
|
-
document: document,
|
19
|
-
raw: raw_result).perform!
|
20
|
-
```
|
@@ -1,59 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module GraphQL
|
4
|
-
module Stitching
|
5
|
-
class Document
|
6
|
-
SUPPORTED_OPERATIONS = ["query", "mutation"].freeze
|
7
|
-
|
8
|
-
attr_reader :ast, :operation_name
|
9
|
-
|
10
|
-
def initialize(string_or_ast, operation_name: nil)
|
11
|
-
@ast = if string_or_ast.is_a?(String)
|
12
|
-
GraphQL.parse(string_or_ast)
|
13
|
-
else
|
14
|
-
string_or_ast
|
15
|
-
end
|
16
|
-
|
17
|
-
@operation_name = operation_name
|
18
|
-
end
|
19
|
-
|
20
|
-
def string
|
21
|
-
@string ||= GraphQL::Language::Printer.new.print(@ast)
|
22
|
-
end
|
23
|
-
|
24
|
-
def digest
|
25
|
-
@digest ||= Digest::SHA2.hexdigest(string)
|
26
|
-
end
|
27
|
-
|
28
|
-
def operation
|
29
|
-
@operation ||= begin
|
30
|
-
operation_defs = @ast.definitions.select do |d|
|
31
|
-
next unless d.is_a?(GraphQL::Language::Nodes::OperationDefinition)
|
32
|
-
next unless SUPPORTED_OPERATIONS.include?(d.operation_type)
|
33
|
-
@operation_name ? d.name == @operation_name : true
|
34
|
-
end
|
35
|
-
|
36
|
-
if operation_defs.length < 1
|
37
|
-
raise GraphQL::ExecutionError, "Invalid root operation."
|
38
|
-
elsif operation_defs.length > 1
|
39
|
-
raise GraphQL::ExecutionError, "An operation name is required when sending multiple operations."
|
40
|
-
end
|
41
|
-
|
42
|
-
operation_defs.first
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
def variable_definitions
|
47
|
-
@variable_definitions ||= operation.variables.each_with_object({}) do |v, memo|
|
48
|
-
memo[v.name] = v.type
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
def fragment_definitions
|
53
|
-
@fragment_definitions ||= @ast.definitions.each_with_object({}) do |d, memo|
|
54
|
-
memo[d.name] = d if d.is_a?(GraphQL::Language::Nodes::FragmentDefinition)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|