GraphQL Federation


Apollo Federation provides a mechanism to combine multiple GraphQL endpoints and schema into a single aggregate endpoint and composite schema. The basic principles of GraphQL federation are as follows:

  1. Collects the schemas from multiple endpoints.

  2. Combines the schemas into a single composite schema.

  3. Serves the single composite schema to the user completely hiding the inner dependencies.

  4. When a query is performed, the Federation Gateway calls each of the endpoints in a specific order and combines their responses.

Quick Start

Create a docker-compose.yaml that manages all the required services for an aggregate federated SWAPI GraphQL endpoint that joins Semantic Objects and a simple example Apollo Server:

  • Federation Gateway

  • Semantic Objects Service (Loaded with SWAPI data and Schema)

  • Example Extended SWAPI Service

  • GraphDB (Loaded with SWAPI data)

  • MongoDB (for storing and managing the schema)

The Ontotext Platform is available under a commercial time-based license. To obtain an evaluation license, please contact us at and see the documentation on Setting up Licenses .

Use this environment file .env to configure the location of the Ontotext Platform license and GraphDB license.

Create a simple bash script for starting everything, loading the SWAPI data and schema. You can also see the Semantic Objects getting started guide.

Download the GraphDB repository configuration, SWAPI data and SOML schema following the Semantic Objects getting started guide and place them in the same directory as the setup script. You should have the following files in the directory: data.ttl, repo.ttl and schema.yaml.

Run the set-up script. To start the services, load the data and build a federated aggregate GraphQL endpoint, use the following shell command:

chmod +x ./ && ./


The setup script and the .env file should be in the same directory as the docker-compose.yaml file.

Try out a GraphQL query against the federated aggregate schema using this cURL command:

curl 'http://localhost:9000/graphql' \
      -H 'Accept: application/json' \
      -H 'Content-Type: application/json' \
      --data-binary '{"query":"query { planet(where: {ID: \"\"}) { name diameter gravity } }"}' \

That returns the Planet Dantooine with the extended calculated gravity property.

  "data": {
    "planet": [
        "name": "Dantooine",
        "diameter": 9830,
        "gravity": "1 standard"


You can also open the OTP Workbench on http://localhost:9993. It is configured to send queries against the Apollo Gateway.


You can find more details on how to use Semantic Objects in this tutorial.


  • The @key directive for all types is set to their ID, although the Apollo Federation server supports each field to be used as key.

  • The current Apollo Gateway implementation (ontotext/apollo-federation-gateway) will not update the aggregated schema if an endpoint’s schema changes. So changing the schema of a federated endpoint requires a Gateway restart.

Schema changes

When a schema change occurs in the Ontotext Platform or other external services used by the Apollo gateway, it must be restarted in order to get the combined schema rebuilt. In case the Apollo gateway does not start propertly, please check its logs for more information about what might be wrong with the combined schema.



Health Check

The Apollo Federation Gateway has an aggregate health check that checks all configured federated services for health status.

The __health endpoint can be accessed at http://{federationhost}:{federation_port}/__health.

An example response is as follows, and you can see the Semantic Objects health response aggregated with the extended service:

  "status": "OK",
  "id": "apollo-federation-gateway",
  "healthChecks": [
      "status": "OK",
      "healthChecks": [
          "status": "OK",
          "id": "1100",
          "name": "MongoDB checks",
          "type": "mongo",
          "impact": "MongoDB operating normally and collection available.",
          "troubleshooting": "http://semantic-objects:8080/__trouble",
          "description": "MongoDB checks.",
          "message": "MongoDB operating normally and collection available."
          "status": "OK",
          "id": "1200",
          "name": "SPARQL checks",
          "type": "sparql",
          "impact": "SPARQL Endpoint operating normally, writable and populated with data.",
          "troubleshooting": "http://semantic-objects:8080/__trouble",
          "description": "SPARQL Endpoint checks.",
          "message": "SPARQL Endpoint operating normally, writable and populated with data."
          "status": "OK",
          "id": "1300",
          "name": "SOML Checks",
          "type": "soml",
          "impact": "SOML bound, service operating normally.",
          "troubleshooting": "http://semantic-objects:8080/__trouble",
          "description": "SOML checks.",
          "message": "SOML bound, service operating normally."
          "status": "OK",
          "id": "1350",
          "type": "soml-rbac",
          "impact": "Security is disabled. SOML RBAC healthcheck is inactive.",
          "troubleshooting": "http://semantic-objects:8080/__trouble",
          "description": "SOML RBAC checks.",
          "message": "Security is disabled. SOML RBAC healthcheck is inactive."
          "status": "OK",
          "id": "1400",
          "name": "Query service",
          "type": "queryService",
          "impact": "Query service operating normally.",
          "troubleshooting": "http://semantic-objects:8080/__trouble",
          "description": "Query service checks.",
          "message": "Query service operating normally."
          "status": "OK",
          "id": "1500",
          "name": "Mutations Service",
          "type": "mutationService",
          "impact": "Mutation Service operating normally.",
          "troubleshooting": "http://semantic-objects:8080/__trouble",
          "description": "Mutation Service checks.",
          "message": "Mutation Service operating normally."
      "status": "OK",
      "id": "example/1",
      "name": "Example Health Check",
      "type": "graphql",
      "healthChecks": []

Good to Go

The Apollo Federation Gateway has an aggregate good to go check that checks all configured federated services for good to go status.

The __gtg endpoint can be accessed at http://{federationhost}:{federation_port}/__gtg.

An example response is as follows:

  "gtg": "OK",
  "message": "Federation Gateway operating as expected"


Federation Gateway

The Federation Gateway is provided as a docker container. The following docker-compose YAML describes the various ENV variables that control the Gateway:

  • GRAPHQL_SERVICE_N: GraphQL endpoint URL address to include within the aggregate schema

  • GRAPHQL_SERVICE_N_GTG: GraphQL endpoint good to go endpoint

  • GRAPHQL_SERVICE_N_HEALTH: GraphQL endpoint health endpoint

  • CACHE_MAX_AGE: cache header max age

  • ENGINE_API_KEY: in case you want to register the federation services with an Apollo Graph Manager

  • SERVICE_DWELL: dwell time between federated GraphQL endpoint health checks

  • POLL_INTERVAL: the interval between federated GraphQL endpoint health checks (start-up)

You can download and use this example docker-compose.yaml configuration.

Federation Gateway Authorization

If the Platform (Semantic Objects) has security enabled, the Federation Gateway must authenticate and retrieve an Authorization JWT token.

This token is used by the Gateway to make authorized requests to federated services to retrieve each GraphQL _service.sdl schema.

After that, the Gateway builds the aggregate schema and discards the token.

Subsequent GraphQL query and mutation requests will use the client’s Authorization header.

The following ENV variables control the Gateway schema aggregation authorization:

  • SECURITY_ENABLED: true - schema building uses FusionAuth supplied authorization tokens, otherwise no authorization

  • FUSION_APPLICATION_ID: The FusionAuth Application UUID for the Platform, e.g., “0afceebe-cfc6-4ddf-81b9-a7fd658b30d4”

  • FUSION_PROTOCOL: The protocol to use when connecting to the FusionAuth REST API “http” | “https”

  • FUSION_HOST: The server host to use when connecting to the FusionAuth REST API, e.g., “localhost”

  • FUSION_PORT: The TCP/IP port to use when connecting to the FusionAuth REST API, e.g., “9011”

  • FUSION_USERNAME: The FusionAuth username to use when authenticating, e.g., “federation”

  • FUSION_PASSWORD: The FusionAuth password to use when authentication, e.g., “federation”

  • FORWARD_HEADERS: The HTTP headers the Gateway should forward to federated GraphQL endpoints “X-Request-ID, Authorization”

  • FUSION_LOGIN_RETRIES: The number of authentication re-tries before giving up. Default “10”

  • FUSION_LOGIN_RETRY_DELAY: The number of milliseconds between each authentication retry. Default “2000”

As mentioned above, in order for the Federation Gateway to retrieve the SDL, it needs a user with sufficient rights to do so. So first, add the following role to the SOML (it provides gives read permissions to the SDL):

      description: "Federation service role"
      actions: [

The next step is to add the user in FusionAuth. The user should have role Federation and username and password matching the ones defined in FUSION_USERNAME and FUSION_PASSWORD environment variables.

If you are using the OPCTL tool to provision the security, add the following to the configuration yaml:

    - name: Federation
      superRole: false
      default: false
    - username: federation
      password: federation
        - Federation

Once you have a configured user and role, the Federation Gateway will be able to operate properly.

Federation Correlation

The Federation Gateway will generate X-Request-ID correlation ids if none are present on requests. X-Request-ID is always logged and forwarded to federated GraphQL endpoints.

This ensures that a GraphQL query or mutation can be traced and correlated across the Gateway, Federated GraphQL services and indeed GraphDB.

The dockerfile by default should include the following headers for forwarding:

  • FORWARD_HEADERS: “X-Request-ID, Authorization”

X-Request-ID is the Platform default correlation id HTTP header.

Semantic Objects Service

SOaaS supports the Apollo Federation protocol and can be a part of an Apollo Federation (with some known limitations).

To make the SOaaS endpoint federation-ready, you need to enable the following property:


This will make all necessary additions to the GraphQL schema.