22id : federated-schemas
33title : Federated Schemas
44---
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
2217([ 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.
2418
2519** In order to generate valid federated schemas, you will need to annotate both your base schema and the one extending
2620it** . 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
3226
3327Base schema defines GraphQL types that will be extended by schemas exposed by other GraphQL services. In the example
3428below, 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.
3631
3732``` kotlin
3833@KeyDirective(fields = FieldSet (" id" ))
@@ -52,7 +47,7 @@ val queries = listOf(TopLevelObject(ProductQuery()))
5247toFederatedSchema(config, queries)
5348```
5449
55- Generates the following schema with additional federated types
50+ Example above generates the following schema with additional federated types:
5651
5752``` graphql
5853schema {
@@ -83,7 +78,9 @@ Extended federated GraphQL schemas provide additional functionality to the types
8378services . In the example below , `Product ` type is extended to add new `reviews ` field to it . Primary key needed to
8479instantiate the `Product ` type (i.e. `id`) has to match the `@key ` definition on the base type . Since primary keys are
8580defined 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 .
8784
8885```kotlin
8986@KeyDirective (fields = FieldSet("id" ))
@@ -110,7 +107,7 @@ val config = FederatedSchemaGeneratorConfig(supportedPackages = listOf("org.exam
110107toFederatedSchema (config)
111108```
112109
113- Generates the following federated schema
110+ Our extended schema will then be generated as:
114111
115112``` graphql
116113schema {
@@ -141,7 +138,8 @@ type _Service {
141138
142139#### Federated GraphQL schema
143140
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:
145143
146144```graphql
147145schema {
@@ -163,3 +161,5 @@ type Query {
163161 product (id : String ! ): Product !
164162}
165163```
164+
165+ See our [federation example ](https ://github .com /ExpediaGroup /graphql -kotlin /tree /master /examples /federation ) for additional details .
0 commit comments