graphql-stitching 1.2.2 → 1.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6753e205aac88d3dd3be1c906b743cc49ae0de84ff8ab56c7e9be6e889429aa3
4
- data.tar.gz: 59440f9d70cb365ef124604c42012bf655934555dfb76905328368353f5e310b
3
+ metadata.gz: 99acc247a0e5e227236b0261b3f975e7277f642a9d76daaf4f6a985bfc4825ea
4
+ data.tar.gz: ef5f01132498ca4ba1be6f8593f189645ddf8fb6b6d8ab71f9b7d0e55d6ec682
5
5
  SHA512:
6
- metadata.gz: ac218d2218c14b8debff552ffb11e83e00293dfebb404d25296ed9e408232e488c44575c701ee3fd933331d84755062517f2c2da8df2db98ac7c5e8594595846
7
- data.tar.gz: ec4f5051ebd511e72536c8e3246302079b2eb65ab5edab37c7c7d7de5488cdc7581318c69a0ea54047bd79ff42bf9e9c5af3434a27fc5667cf029340527c8117
6
+ metadata.gz: d1bd0db4c7f6d363231330222006f2bbc552a669227a38aeb7861dde843b59bc3e61b0f301f97d4a5c6b55193d01424cd9f240c0ff7a7ee483e49150686ac3da
7
+ data.tar.gz: 348aa663608fd8b0e5544ccf7ec500d4295a63bb9bd19a91031f927165da2a206024ce6cb17111c3ebda2c172e08072be8d01716c11f0a05c3ea8a9a4b99466e
@@ -16,10 +16,16 @@ jobs:
16
16
  ruby: 3.2
17
17
  - gemfile: Gemfile
18
18
  ruby: 3.1
19
- - gemfile: gemfiles/graphql_1.13.9.gemfile
20
- ruby: 3.1
21
19
  - gemfile: Gemfile
22
20
  ruby: 2.7
21
+ - gemfile: gemfiles/graphql_2.2.0.gemfile
22
+ ruby: 3.1
23
+ - gemfile: gemfiles/graphql_2.1.0.gemfile
24
+ ruby: 3.1
25
+ - gemfile: gemfiles/graphql_2.0.0.gemfile
26
+ ruby: 3.1
27
+ - gemfile: gemfiles/graphql_1.13.9.gemfile
28
+ ruby: 3.1
23
29
 
24
30
  steps:
25
31
  - uses: actions/checkout@v2
data/README.md CHANGED
@@ -9,14 +9,13 @@ GraphQL stitching composes a single schema from multiple underlying GraphQL reso
9
9
  - Multiple keys per merged type.
10
10
  - Shared objects, fields, enums, and inputs across locations.
11
11
  - Combining local and remote schemas.
12
- - Type merging via arbitrary queries or federation `_entities` protocol.
13
12
  - File uploads via [multipart form spec](https://github.com/jaydenseric/graphql-multipart-request-spec).
14
13
 
15
14
  **NOT Supported:**
16
15
  - Computed fields (ie: federation-style `@requires`).
17
16
  - Subscriptions, defer/stream.
18
17
 
19
- This Ruby implementation is a sibling to [GraphQL Tools](https://the-guild.dev/graphql/stitching) (JS) and [Bramble](https://movio.github.io/bramble/) (Go), and its capabilities fall somewhere in between them. GraphQL stitching is similar in concept to [Apollo Federation](https://www.apollographql.com/docs/federation/), though more generic. While Ruby is not the fastest language for a purely high-throughput API gateway, the opportunity here is for a Ruby application to stitch its local schemas together or onto remote sources without requiring an additional proxy service running in another language.
18
+ This Ruby implementation is a sibling to [GraphQL Tools](https://the-guild.dev/graphql/stitching) (JS) and [Bramble](https://movio.github.io/bramble/) (Go), and its capabilities fall somewhere in between them. GraphQL stitching is similar in concept to [Apollo Federation](https://www.apollographql.com/docs/federation/), though more generic. The opportunity here is for a Ruby application to stitch its local schemas together or onto remote sources without requiring an additional proxy service running in another language. If your goal is to build a purely high-throughput API gateway, consider not using Ruby.
20
19
 
21
20
  ## Getting started
22
21
 
@@ -34,7 +33,7 @@ require "graphql/stitching"
34
33
 
35
34
  ## Usage
36
35
 
37
- The quickest way to start is to use the provided [`Client`](./docs/client.md) component that wraps a stitched graph in an executable workflow with [caching hooks](./docs/client.md#cache-hooks):
36
+ The quickest way to start is to use the provided [`Client`](./docs/client.md) component that wraps a stitched graph in an executable workflow (with optional query plan caching hooks):
38
37
 
39
38
  ```ruby
40
39
  movies_schema = <<~GRAPHQL
@@ -72,7 +71,7 @@ result = client.execute(
72
71
  )
73
72
  ```
74
73
 
75
- Schemas provided in [location settings](./docs/composer.md#performing-composition) may be class-based schemas with local resolvers (locally-executable schemas), or schemas built from SDL strings (schema definition language parsed using `GraphQL::Schema.from_definition`) and mapped to remote locations. See [composer docs](./docs/composer.md#merge-patterns) for more information on how schemas get merged.
74
+ Schemas provided in [location settings](./docs/composer.md#performing-composition) may be class-based schemas with local resolvers (locally-executable schemas), or schemas built from SDL strings (schema definition language parsed using `GraphQL::Schema.from_definition`) and mapped to remote locations via [executables](#executables).
76
75
 
77
76
  While the `Client` constructor is an easy quick start, the library also has several discrete components that can be assembled into custom workflows:
78
77
 
@@ -87,11 +86,11 @@ While the `Client` constructor is an easy quick start, the library also has seve
87
86
 
88
87
  ![Merging types](./docs/images/merging.png)
89
88
 
90
- To facilitate this merging of types, stitching must know how to cross-reference and fetch each variant of a type from its source location. This can be done using [arbitrary queries](#merged-types-via-arbitrary-queries) or [federation entities](#merged-types-via-federation-entities).
89
+ To facilitate this merging of types, stitching must know how to cross-reference and fetch each variant of a type from its source location using [resolver queries](#merged-type-resolver-queries). For those in an Apollo ecosystem, there's also _limited_ support for merging types though a [federation `_entities` protocol](./docs/federation_entities.md).
91
90
 
92
- ### Merged types via arbitrary queries
91
+ ### Merged type resolver queries
93
92
 
94
- Types can merge through arbitrary queries using the `@stitch` directive:
93
+ Types merge through resolver queries identified by a `@stitch` directive:
95
94
 
96
95
  ```graphql
97
96
  directive @stitch(key: String!) repeatable on FIELD_DEFINITION
@@ -299,65 +298,6 @@ The library is configured to use a `@stitch` directive by default. You may custo
299
298
  GraphQL::Stitching.stitch_directive = "merge"
300
299
  ```
301
300
 
302
- ### Merged types via Federation entities
303
-
304
- The [Apollo Federation specification](https://www.apollographql.com/docs/federation/subgraph-spec/) defines a standard interface for accessing merged type variants across locations. Stitching can utilize a _subset_ of this interface to facilitate basic type merging. The following spec is supported:
305
-
306
- - `@key(fields: "id")` (repeatable) specifies a key field for an object type. The key `fields` argument may only contain one field selection.
307
- - `_Entity` is a union type that must contain all types that implement a `@key`.
308
- - `_Any` is a scalar that recieves raw JSON objects; each object representation contains a `__typename` and the type's key field.
309
- - `_entities(representations: [_Any!]!): [_Entity]!` is a root query for local entity types.
310
-
311
- The composer will automatcially detect and stitch schemas with an `_entities` query, for example:
312
-
313
- ```ruby
314
- products_schema = <<~GRAPHQL
315
- directive @key(fields: String!) repeatable on OBJECT
316
-
317
- type Product @key(fields: "id") {
318
- id: ID!
319
- name: String!
320
- }
321
-
322
- union _Entity = Product
323
- scalar _Any
324
-
325
- type Query {
326
- user(id: ID!): User
327
- _entities(representations: [_Any!]!): [_Entity]!
328
- }
329
- GRAPHQL
330
-
331
- catalog_schema = <<~GRAPHQL
332
- directive @key(fields: String!) repeatable on OBJECT
333
-
334
- type Product @key(fields: "id") {
335
- id: ID!
336
- price: Float!
337
- }
338
-
339
- union _Entity = Product
340
- scalar _Any
341
-
342
- type Query {
343
- _entities(representations: [_Any!]!): [_Entity]!
344
- }
345
- GRAPHQL
346
-
347
- client = GraphQL::Stitching::Client.new(locations: {
348
- products: {
349
- schema: GraphQL::Schema.from_definition(products_schema),
350
- executable: ...,
351
- },
352
- catalog: {
353
- schema: GraphQL::Schema.from_definition(catalog_schema),
354
- executable: ...,
355
- },
356
- })
357
- ```
358
-
359
- It's perfectly fine to mix and match schemas that implement an `_entities` query with schemas that implement `@stitch` directives; the protocols achieve the same result. Note that stitching is much simpler than Apollo Federation by design, and that Federation's advanced routing features (such as the `@requires` and `@external` directives) will not work with stitching.
360
-
361
301
  ## Executables
362
302
 
363
303
  An executable resource performs location-specific GraphQL requests. Executables may be `GraphQL::Schema` classes, or any object that responds to `.call(request, source, variables)` and returns a raw GraphQL response:
@@ -427,6 +367,7 @@ The [Executor](./docs/executor.md) component builds atop the Ruby fiber-based im
427
367
 
428
368
  - [Modeling foreign keys for stitching](./docs/mechanics.md##modeling-foreign-keys-for-stitching)
429
369
  - [Deploying a stitched schema](./docs/mechanics.md#deploying-a-stitched-schema)
370
+ - [Schema composition merge patterns](./docs/composer.md#merge-patterns)
430
371
  - [Field selection routing](./docs/mechanics.md#field-selection-routing)
431
372
  - [Root selection routing](./docs/mechanics.md#root-selection-routing)
432
373
  - [Stitched errors](./docs/mechanics.md#stitched-errors)
@@ -0,0 +1,70 @@
1
+ ## Merged types via Apollo Federation `_entities`
2
+
3
+ The [Apollo Federation specification](https://www.apollographql.com/docs/federation/subgraph-spec/) defines a standard interface for accessing merged type variants across locations. Stitching can utilize a _subset_ of this interface to facilitate basic type merging; the full spec is NOT supported and therefore is not fully interchangable with an Apollo Gateway.
4
+
5
+ To avoid confusion, using [basic resolver queries](../README.md#merged-type-resolver-queries) is recommended unless you specifically need to interact with a service built for an Apollo ecosystem. Even then, be wary that it does not exceed the supported spec by [using features that will not work](#federation-features-that-will-most-definitly-break).
6
+
7
+ ### Supported spec
8
+
9
+ The following subset of the federation spec is supported:
10
+
11
+ - `@key(fields: "id")` (repeatable) specifies a key field for an object type. The key `fields` argument may only contain one field selection.
12
+ - `_Entity` is a union type that must contain all types that implement a `@key`.
13
+ - `_Any` is a scalar that recieves raw JSON objects; each object representation contains a `__typename` and the type's key field.
14
+ - `_entities(representations: [_Any!]!): [_Entity]!` is a root query for local entity types.
15
+
16
+ The composer will automatcially detect and stitch schemas with an `_entities` query, for example:
17
+
18
+ ```ruby
19
+ products_schema = <<~GRAPHQL
20
+ directive @key(fields: String!) repeatable on OBJECT
21
+
22
+ type Product @key(fields: "id") {
23
+ id: ID!
24
+ name: String!
25
+ }
26
+
27
+ union _Entity = Product
28
+ scalar _Any
29
+
30
+ type Query {
31
+ user(id: ID!): User
32
+ _entities(representations: [_Any!]!): [_Entity]!
33
+ }
34
+ GRAPHQL
35
+
36
+ catalog_schema = <<~GRAPHQL
37
+ directive @key(fields: String!) repeatable on OBJECT
38
+
39
+ type Product @key(fields: "id") {
40
+ id: ID!
41
+ price: Float!
42
+ }
43
+
44
+ union _Entity = Product
45
+ scalar _Any
46
+
47
+ type Query {
48
+ _entities(representations: [_Any!]!): [_Entity]!
49
+ }
50
+ GRAPHQL
51
+
52
+ client = GraphQL::Stitching::Client.new(locations: {
53
+ products: {
54
+ schema: GraphQL::Schema.from_definition(products_schema),
55
+ executable: ...,
56
+ },
57
+ catalog: {
58
+ schema: GraphQL::Schema.from_definition(catalog_schema),
59
+ executable: ...,
60
+ },
61
+ })
62
+ ```
63
+
64
+ It's perfectly fine to mix and match schemas that implement an `_entities` query with schemas that implement `@stitch` directives; the protocols achieve the same result.
65
+
66
+ ### Federation features that will most definitly break
67
+
68
+ - `@external` fields will confuse the stitching query planner.
69
+ - `@requires` fields will not be sent any dependencies.
70
+ - No support for Apollo composition directives.
@@ -3,4 +3,4 @@
3
3
  source 'https://rubygems.org'
4
4
  gemspec
5
5
 
6
- gem 'graphql', '1.13.9'
6
+ gem 'graphql', '~> 1.13.9'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ gem 'graphql', '~> 2.0.0'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ gem 'graphql', '~> 2.1.0'
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+ gemspec
5
+
6
+ gem 'graphql', '~> 2.2.0'
@@ -145,7 +145,8 @@ module GraphQL
145
145
 
146
146
  builder = self
147
147
  schema = Class.new(GraphQL::Schema) do
148
- orphan_types schema_types.values
148
+ add_type_and_traverse(schema_types.values, root: false)
149
+ orphan_types(schema_types.values.select { |t| t.respond_to?(:kind) && t.kind.object? })
149
150
  query schema_types[builder.query_name]
150
151
  mutation schema_types[builder.mutation_name]
151
152
  directives builder.schema_directives.values
@@ -2,6 +2,6 @@
2
2
 
3
3
  module GraphQL
4
4
  module Stitching
5
- VERSION = "1.2.2"
5
+ VERSION = "1.2.3"
6
6
  end
7
7
  end
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: 1.2.2
4
+ version: 1.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Greg MacWilliam
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-02-11 00:00:00.000000000 Z
11
+ date: 2024-04-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: graphql
@@ -82,6 +82,7 @@ files:
82
82
  - docs/README.md
83
83
  - docs/client.md
84
84
  - docs/composer.md
85
+ - docs/federation_entities.md
85
86
  - docs/http_executable.md
86
87
  - docs/images/library.png
87
88
  - docs/images/merging.png
@@ -104,6 +105,9 @@ files:
104
105
  - examples/merged_types/remote1.rb
105
106
  - examples/merged_types/remote2.rb
106
107
  - gemfiles/graphql_1.13.9.gemfile
108
+ - gemfiles/graphql_2.0.0.gemfile
109
+ - gemfiles/graphql_2.1.0.gemfile
110
+ - gemfiles/graphql_2.2.0.gemfile
107
111
  - graphql-stitching.gemspec
108
112
  - lib/graphql/stitching.rb
109
113
  - lib/graphql/stitching/boundary.rb