GraphQL Introspection Tutorial

What’s in this document?

The following sections provide short examples of GraphQL introspection queries and responses. If you have started the services following the Quick Start 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.

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlVWWHMyZ2hidFhBSUtyc2V5QnduTVYzR0dBSEZaRzMwIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE2NjAyOTExMDksImlhdCI6MTU5NzIxOTEwOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiM2I2YzA3MjktNTJiMC00NDk4LWIxZGUtOTE4YjZjMTU4N2M5IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXX0.KIoFrune5hKqkHDr4BgRbaHZyrkoYoCq9SPBuN9NLxE
true
{ __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:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlVWWHMyZ2hidFhBSUtyc2V5QnduTVYzR0dBSEZaRzMwIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE2NjAyOTExMDksImlhdCI6MTU5NzIxOTEwOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiM2I2YzA3MjktNTJiMC00NDk4LWIxZGUtOTE4YjZjMTU4N2M5IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXX0.KIoFrune5hKqkHDr4BgRbaHZyrkoYoCq9SPBuN9NLxE
true
{ __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:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlVWWHMyZ2hidFhBSUtyc2V5QnduTVYzR0dBSEZaRzMwIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE2NjAyOTExMDksImlhdCI6MTU5NzIxOTEwOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiM2I2YzA3MjktNTJiMC00NDk4LWIxZGUtOTE4YjZjMTU4N2M5IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXX0.KIoFrune5hKqkHDr4BgRbaHZyrkoYoCq9SPBuN9NLxE
true
{ __type(name: "Character") { name kind } }

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

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlVWWHMyZ2hidFhBSUtyc2V5QnduTVYzR0dBSEZaRzMwIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE2NjAyOTExMDksImlhdCI6MTU5NzIxOTEwOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiM2I2YzA3MjktNTJiMC00NDk4LWIxZGUtOTE4YjZjMTU4N2M5IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXX0.KIoFrune5hKqkHDr4BgRbaHZyrkoYoCq9SPBuN9NLxE
true
{ __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:

Loading...
https://swapi-platform.ontotext.com/graphql
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlVWWHMyZ2hidFhBSUtyc2V5QnduTVYzR0dBSEZaRzMwIn0.eyJhdWQiOiI2NzJjYTdiMy1jMzcyLTRkZjMtODJkOC05YTFhMGQ3ZDY4YzEiLCJleHAiOjE2NjAyOTExMDksImlhdCI6MTU5NzIxOTEwOSwiaXNzIjoic3dhcGktcGxhdGZvcm0ub250b3RleHQuY29tIiwic3ViIjoiM2I2YzA3MjktNTJiMC00NDk4LWIxZGUtOTE4YjZjMTU4N2M5IiwiYXV0aGVudGljYXRpb25UeXBlIjoiUEFTU1dPUkQiLCJlbWFpbCI6InJlYWRvbmx5dXNlckBleGFtcGxlLmNvbSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJwcmVmZXJyZWRfdXNlcm5hbWUiOiJSZWFkT25seVVzZXIiLCJhcHBsaWNhdGlvbklkIjoiNjcyY2E3YjMtYzM3Mi00ZGYzLTgyZDgtOWExYTBkN2Q2OGMxIiwicm9sZXMiOlsiUmVhZE9ubHkiXX0.KIoFrune5hKqkHDr4BgRbaHZyrkoYoCq9SPBuN9NLxE
true
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 } } } }