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)