Federated Type Resolution
In traditional (i.e. non-federated) GraphQL servers, each one of the output types is accessible through a traversal of the GraphQL schema from a corresponding query, mutation or subscription root type. Since federated GraphQL types might be accessed outside of the query path we need a mechanism to access them in a consistent manner.
_entities query
Federated GraphQL server provides custom _entities query that allow retrieving any of the federated extended types.
_entities query accept list of "representation" objects that provide all required fields to resolve the type and
return an _Entity union type of all supported federated types. Representation objects are just a map of all the fields
referenced in @key directive as well as target __typename information. If federated query type fragments also
reference fields with @requires and @provides directives then those referenced fields should also be specified in
the target representation object.
> NOTE: _entities queries are automatically generated by the federated gateway and their usage is transparent for the
> gateway clients.
query ($_representations: [_Any!]!) {
_entities(representations: $_representations) {
... on SomeFederatedType {
fieldA
fieldB
}
}
}
Federated Type Resolver
In order to simplify the integrations, graphql-kotlin-federation provides default _entities query resolver that
relies on
FederatedTypeRegistry
to retrieve
FederatedTypeResolver
that is used to resolve target object. When configuring the federated schema generator hooks you have to explicitly
provide those resolver mappings to the configuration.
FederatedTypeResolver accepts a list of representations of the target types which should be resolved in the same order
as they were specified in the list of representations. Each passed in representation should either be resolved to a
target entity or NULL if entity cannot be resolved.
val productResolver = object: FederatedTypeResolver<Product> {
override suspend fun resolve(representations: List<Map<String, Any>>): List<Product?> = representations.map {
val id = it["id"]?.toString()?.toIntOrNull()
// instantiate product using id
}
}
// federated type registry provides mapping between target __typename and the corresponding type resolver
val federatedTypeRegistry = FederatedTypeRegistry(mapOf("Product" to productResolver))
val config = FederatedSchemaGeneratorConfig(supportedPackages = listOf("org.example"), hooks = FederatedSchemaGeneratorHooks(federatedTypeRegistry))
val schema = toFederatedSchema(config)