Skip to content

An extension adding GraphQL federation support to HotChocolate framework based on Apollo Federation Spec

License

Notifications You must be signed in to change notification settings

lampidudelj/HotChocolate.ApolloFederationExtension

Repository files navigation

HotChocolate Apollo Federation Extension

CI

An extension adding GraphQL federation support to HotChocolate framework based on Apollo Federation Spec

Getting Started

Add the federated extension to the service configuration by adding the following code to the ConfigureServices method in the Startup.cs.

   services
       .AddGraphQLServer()
       .AddFederationExtensions()
       .AddQueryType<Query>()

   services.AddHttpContextAccessor();

This will extend your server and schema with Fetch Service capability and custom federation scalars, unions and directives

Using annotation to extend types

The extension provides both Object and Field level directives to generate federation spec compliant schema For example, following class will generate:

    [FederationObjectDirective(Name = "key", Fields = "id")]
    [FederationObjectDirective(Name = "extends")]
    public record Hotel([property: FederationFieldDirective(Name = "external")]
                        [property: GraphQLType(typeof(NonNullType<IdType>))] 
                        int Id, 
                        Destination Destination) : IEntityUnionType
    {
        [GraphQLIgnore]
        public IEntityUnionType ResolveReference(KeyValuePair<string, object> primaryKey)
        {
            if (primaryKey.Key == "id")
            {
                return GetById((int)primaryKey.Value);
            }

            return null;
        }
    }

following schema

    type Hotel @key(fields: "id") @extends {
        id: ID! @external
    }

    union _Entity = Hotel

Key points

  • any type annotated with the @key directive, including both types native to the schema and extended types, must implement IEntityUnionType interface as it serves as a representation of the federation UnionEntity
  • public IEntityUnionType ResolveReference(KeyValuePair<string, object> primaryKey) method is a resolver for a query across service boundaries. It should return an entity based on the key specified in the schema and provided as an input parameter. More on how this works
  • [GraphQLIgnore] attribute must annotate ResolveReference method. HotChocolate's schema builder engine can not serialize KeyValuePair into a GraphQL scalar and will crash trying.

TODO

  • implement @provides and @requires directives.
  • validation on _Any and _FieldSet scalars
  • better solution to getting schema for _service resolver. Cache?
  • input type for KeyValuePair to get around having to use [GraphQLIgnore] attribute_