2
2
id : federated-schemas
3
3
title : Federated Schemas
4
4
---
5
- In many cases, exposing single GraphQL API that exposes unified view of all the available data provides tremendous value
6
- to their clients. As the underlying graph scales, managing single monolithic GraphQL server might become less and less
7
- feasible making it much harder to manage and leading to unnecessary bottlenecks. Migrating towards federated model with
8
- an API gateway and a number of smaller GraphQL services behind it alleviates some of those problems and allows teams to
9
- scale their graphs more easily.
10
-
11
- ## Apollo Federation
12
-
13
- [ Apollo Federation] ( https://www.apollographql.com/docs/apollo-server/federation/introduction/ ) is an architecture for
14
- composing multiple GraphQL services into a single graph. Each individual GraphQL server generates valid GraphQL schema
15
- and can be developed and run independently.
16
-
17
- ` graphql-kotlin-federation ` extends the functionality of ` graphql-kotlin-schema-generator ` and allows you to easily
18
- generate federated GraphQL schemas directly from the code. Federated schemas rely on a number of [ new directives] ( federated-directives ) to
19
- instrument the behavior of the underlying graph. Once all the federated objects are annotated, you will also have to configure corresponding
20
- FederatedTypeResolvers that are used to instantiate underlying federated objects and finally generate the schema using
21
- ` toFederatedSchema ` function
5
+
6
+ ` graphql-kotlin-federation ` library extends the functionality of the ` graphql-kotlin-schema-generator ` and allows you to
7
+ easily generate federated GraphQL schemas directly from the code. Federated schema is generated by calling
8
+ ` toFederatedSchema ` function that accepts federated configuration as well as a list of regular queries, mutations and
9
+ subscriptions exposed by the schema.
10
+
11
+ All [ federated directives] ( (federated-directives) ) are provided as annotations that are used to decorate your classes,
12
+ properties and functions. Since federated types might not be accessible through the regular query execution path, they
13
+ are explicitly picked up by the schema generator based on their directives. Due to the above, we also need to provide
14
+ a way to instantiate the underlying federated objects by implementing corresponding ` FederatedTypeResolvers ` . See
15
+ [ type resolution wiki] ( type-resolution ) for more details on how federated types are resolved. Final federated schema
16
+ is then generated by invoking the ` toFederatedSchema ` function
22
17
([ link] ( https://github.com/ExpediaGroup/graphql-kotlin/blob/master/graphql-kotlin-federation/src/main/kotlin/com/expediagroup/graphql/federation/toFederatedSchema.kt#L34 ) ).
23
- See [ type resolution] ( type-resolution ) for more details on how federated types are resolved.
24
18
25
19
** In order to generate valid federated schemas, you will need to annotate both your base schema and the one extending
26
20
it** . Federated Gateway (e.g. Apollo) will then combine the individual graphs to form single federated graph.
@@ -32,7 +26,8 @@ it**. Federated Gateway (e.g. Apollo) will then combine the individual graphs to
32
26
33
27
Base schema defines GraphQL types that will be extended by schemas exposed by other GraphQL services. In the example
34
28
below, we define base ` Product ` type with ` id ` and ` description ` fields. ` id ` is the primary key that uniquely
35
- identifies the ` Product ` type object and is specified in ` @key ` directive.
29
+ identifies the ` Product ` type object and is specified in ` @key ` directive. Since it is a base schema that doesn't expose
30
+ any extended functionality our FederatedTypeRegistry does not include any federated resolvers.
36
31
37
32
``` kotlin
38
33
@KeyDirective(fields = FieldSet (" id" ))
@@ -52,7 +47,7 @@ val queries = listOf(TopLevelObject(ProductQuery()))
52
47
toFederatedSchema(config, queries)
53
48
```
54
49
55
- Generates the following schema with additional federated types
50
+ Example above generates the following schema with additional federated types:
56
51
57
52
``` graphql
58
53
schema {
@@ -83,7 +78,9 @@ Extended federated GraphQL schemas provide additional functionality to the types
83
78
services . In the example below , `Product ` type is extended to add new `reviews ` field to it . Primary key needed to
84
79
instantiate the `Product ` type (i.e. `id`) has to match the `@key ` definition on the base type . Since primary keys are
85
80
defined on the base type and are only referenced from the extended type , all of the fields that are part of the field
86
- set specified in `@key ` directive have to be marked as `@external `.
81
+ set specified in `@key ` directive have to be marked as `@external `. Finally , we also need to specify an "entry point"
82
+ for the federated type - we need to create a FederatedTypeResolver that will be used to instantiate the federated
83
+ `Product ` type when processing federated queries .
87
84
88
85
```kotlin
89
86
@KeyDirective (fields = FieldSet("id" ))
@@ -110,7 +107,7 @@ val config = FederatedSchemaGeneratorConfig(supportedPackages = listOf("org.exam
110
107
toFederatedSchema (config)
111
108
```
112
109
113
- Generates the following federated schema
110
+ Our extended schema will then be generated as:
114
111
115
112
``` graphql
116
113
schema {
@@ -141,7 +138,8 @@ type _Service {
141
138
142
139
#### Federated GraphQL schema
143
140
144
- Federated Gateway will then combine the schemas from the individual services to generate single schema .
141
+ Once we have both base and extended GraphQL services up and running , we will also need to configure Federated Gateway
142
+ to combine them into a single schema . Using the examples above, our final federated schema will be generated as:
145
143
146
144
```graphql
147
145
schema {
@@ -163,3 +161,5 @@ type Query {
163
161
product (id : String ! ): Product !
164
162
}
165
163
```
164
+
165
+ See our [federation example ](https ://github .com /ExpediaGroup /graphql -kotlin /tree /master /examples /federation ) for additional details .
0 commit comments