Skip to main content
Version: 3.x.x

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)