Type resolver
When resolving a field implementing an abstract type (either an Union or an Interface) the engine need to have a way of determining which object a given result corresponds to. This logic is handled by the type resolver.
There is multiple option to define a type resolver
A type resolver can be defined at several levels, from the most precise to the most generic:
- on the
@Resolverof a field by fill in thetype_resolverargument - by decorating a dedicated callable with the
@TypeResolverdecorator - by replacing the default type resolver of the engine with a custom one
@Resolver
The @Resolver accepts a type_resolver optional parameter which expect a callable which must be compliant with the function signature.
from tartiflette import Resolver
@Resolver(
"Query.pet",
type_resolver=lambda: result, context, info, abstract_type: (
"Cat" if "meowVolume" in result else "Dog"
)
)
async def resolve_query_pet(parent, args, context, info):
return {"id": 1, "name": "Cat", "meowVolume": 10}
@TypeResolver
A more generic way to define a type resolver is to provide a dedicated type resolver for an abstract type with the @TypeResolver decorator.
from tartiflette import TypeResolver
@TypeResolver("Pet")
def resolve_pet_type(result, context, info, abstract_type):
return "Cat" if "meowVolume" in result else "Dog"
Notes: the
@TypeResolvercan only be applied to an abstract type.
Overriding the default type resolver
By default, Tartiflette provide a type resolver which will be called when resolving any field which implements an abstract type.
Its default behavior is to get the _typename key, then the _typename attribute and if both failed, it'll return the __class__.__name__ of the result parameter.
This default type resolver can be override by providing a custom one at the engine initialization with the custom_default_type_resolver parameter (more detail here)
Function signature
Every type resolver in Tartiflette accepts four positional arguments:
async def my_type_resolver(
result: Any,
ctx: Optional[Any],
info: "ResolverInfo",
abstract_type: Union["GraphQLInterfaceType", "GraphQLUnionType"],
) -> Any:
pass
result(Any): resolved field resultctx(Optional[Any]): will be the value of thecontextargument provided when calling theexecuteorsubscribe'sEnginemethodinfo(ResolverInfo): informationinternal Tartiflette object containing information related to the execution and the resolved field. It CAN BE used for advanced use-cases (more detail here)abstract_type(Union[GraphQLInterfaceType, GraphQLUnionType]): the GraphQLAbstractType instance to resolve
Resolver info argument
The info argument contains information related to the execution and the resolved field which can be useful for middlewares and advanced use-cases.
Here are the available properties:
field_name(str): name of the resolved fieldfield_nodes(List["FieldNodes"]): AST nodes related to the resolved fieldreturn_type("GraphQLOutputType"): GraphQLOutputType instance of the resolved fieldparent_type("GraphQLObjectType"): GraphQLObjectType of the field's parentpath("Path"): the path traveled until this fieldschema("GraphQLSchema"): the GraphQLSchema instance linked to resolved fieldfragments(Dict[str, "FragmentDefinitionNode"]): a dictionary of fragment definition AST nodes contained in the requestroot_value(Optional[Any]): the initial value corresponding to provided value atexecuteorsubscribemethod calloperation("OperationDefinitionNode"): the AST operation definition node to executevariable_values(Optional[Dict[str, Any]]): the variables provided in the GraphQL requestis_introspection(bool): determines whether or not the resolved field is in a context of an introspection query