GraphQL Introspection Tutorial

The following sections provide short examples of GraphQL introspection queries and responses. If you have started the services following the Getting Started guide, you can also try the queries out and modify them as you see fit.

All examples in this section are based on the Star Wars dataset.

You can find the full SOML tutorial here.

Introspection Queries

GraphQL introspection allows us to query which resources are available in the current API schema. Via this capability, we can see the queries, types, fields, and directives that the API supports.

The introspection system defines __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, and __Directive which are introspective queries. Note that all of them are preceded by two underscores which are exclusively used by GraphQL’s introspection system. We can find out what types are available by querying the __schema field, always available on the root type of a query.

{ __schema { types { name } } }

As you can see a lot of types are being returned:

  • Query, Character, Human, Film, Droid, etc. - These are the ones that we defined in our type system.

  • String, Boolean, Decimal, Integer, Long, etc. - These are scalars that the type system provided.

  • __Schema, __Type, __TypeKind, __Field, __InputValue, __EnumValue, __Directive - These all are preceded with a double underscore, indicating that they are part of the introspection system.

It is often useful to examine one specific type. Let’s take a look at the Human type:

{ __type(name: "Human") { name kind } }

kind returns a __TypeKind enum, one of whose values is OBJECT. If we asked about Character instead, we would find that it is an interface:

{ __type(name: "Character") { name kind } }

It is useful to know what fields are available for an object:

{ __type(name: "Human") { name fields { name type { name kind } } } }

This has just scratched the surface of the introspection system. We can also query for enum values, what interfaces a type implements, and more.

Here is an example of a full GraphQL introspection query:

query IntrospectionQuery { __schema { queryType { name } mutationType { name } subscriptionType { name } types { ...FullType } directives { name description args { ...InputValue } } } } fragment FullType on __Type { kind name description fields(includeDeprecated: true) { name description args { ...InputValue } type { ...TypeRef } isDeprecated deprecationReason } inputFields { ...InputValue } interfaces { ...TypeRef } enumValues(includeDeprecated: true) { name description isDeprecated deprecationReason } possibleTypes { ...TypeRef } } fragment InputValue on __InputValue { name description type { ...TypeRef } defaultValue } fragment TypeRef on __Type { kind name ofType { kind name ofType { kind name ofType { kind name } } } }

Dynamic Schema Introspection

SOaaS defines a custom _Service type that has two fields:

  • sdl - used by the Apollo federation gateway to fetch the schema with specific directives included needed by the gateway. This field has a value only when Apollo federation is enabled with graphql.federation.enabled=true.

  • full_sdl - can be used to get a full GraphQL schema including all custom directives.

You can use the _service.full_sdl to obtain the schema and develop solutions based on the specific information available there. For example, you can get class and property labels by reading the @descr directives and render them in a web application. You can also create dynamic behavior based on RBAC roles that can be obtained from the @hasRole directives generated in the GraphQL schema.

To fetch a full GraphQL schema including all custom directives like @hasRole and @descr, execute an introspection query like this:

{ _service { full_sdl } }