GitHub

GraphQL Fragment Introspection

In order for Apollo to properly match fragment types, the GraphQL schema must be fetched, processed, added to the codebase, and loaded into the ApolloClient cache.

Fetching and Processing

To help streamline the process, Daffodil provides a @daffodil/builders package that contains the generateFragmentTypes builder. This builder will fetch the schema from the specified URL and write the processed data to the specified file.

We recommend adding a command to your angular.json to generate fragment types. The following example demonstrates this for a mage2docker backend.

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "",
  "projects": {
    "app": {
      ...
      "architect": {
        "generateFragmentTypes": {
          "builder": "@daffodil/builders:generateFragmentTypes",
          "options": {
            "url": "",
            "path": ""
          },
          "configurations": {
            "magento-local": {
              "url": "https://magento2.test/graphql",
              "path": "src/app/fragmentTypes.json"
            }
          }
        },
        ...
      }
    }
  },
  ...
}

fragmentTypes.json can then be generated with the single command:

NODE_TLS_REJECT_UNAUTHORIZED=0 ng run app:generateFragmentTypes -c magento-local

Note that using NODE_TLS_REJECT_UNAUTHORIZED=0 is unsafe. It is recommended only for local services using self-signed certificates, such as mage2docker.

Refer to the @daffodil/builders README for more info.

Adding to the Codebase

The generated JSON document containing fragment types can and should be committed to source control.

An alternative is to generate the schema during a build and release phase, during CI for example. This is up to the developer.

Loading into Apollo Cache

Once the fragment types JSON document has been generated and added to the codebase, it needs to be loaded into cache.

The following example shows a possible Apollo configuration that creates an introspection fragment matcher and loads it into the in-memory cache.

import { provideApollo, Apollo } from 'apollo-angular';
import { IntrospectionFragmentMatcher, InMemoryCache } from 'apollo-cache-inmemory';
import { HttpLinkModule, HttpLink } from 'apollo-angular-link-http';

import introspectionQueryResultData from './fragmentTypes.json';

const fragmentMatcher = new IntrospectionFragmentMatcher({
  introspectionQueryResultData
});

const cache = new InMemoryCache({ fragmentMatcher });

@NgModule({
  ...,
  imports: [
    ...,
    HttpLinkModule
  ],
    providers: [
        provideApollo(myApolloOptionsFactory)
    ]
})
class AppModule {
  constructor(apollo: Apollo, httpLink: HttpLink) {
    apollo.create({
      link: ApolloLink.from([
        httpLink.create({
          uri: 'https://magento2.test/graphql',
          withCredentials: false,
        }),
      ]),
      cache,
    });
  }
}