This article is part of module on GraphQL Introspection in upcoming free GraphQL Language course. We expect that reader has at least some familiarity with basic GraphQL concepts. Otherwise you can go through some of our older articles on medium publication or check out other available resources.
In previous chapters we’ve discussed how the GraphQL language is strongly typed. This is a great advantage over REST APIs. The GraphQL type system not only reduces errors, but also helps us to design the system with much better architecture. In addition, the type system allows us to develop various tools and mechanisms that can increase efficiency of development. One of the best examples of this is the GraphiQL tool from Facebook, which we use throughout the course. With the GraphiQL tool we are able to query the whole type system of the schema. This helps us to document schema live or use GraphiQL for our development. It also allows us to use introspection queries to gain infromation about the type system and reduce the frontend complexity. In this article we will go deeper into how introspection queries work, what kind of introspection queries we can use; and how we can apply them.
All introspection queries in GraphQL are prefixed with two underscores, e.g. __schema. Therefore in the GraphQL schema we cannot define the new fields with this prefix in the name. We need to be sure to avoid naming collisions. Therefore all names with this prefix are not valid in common type fields. According to the specification, we have the following options for introspection queries: __schema, __type and __typename. Using SDL (schema definition language) we can define these queries as follows:
In every GraphQL server we should be able to execute these introspection queries within the Query operation type.
The most important query, which is also used as the primary source for GraphiQL itself is the query that enables us to fetch the whole schema. The name of this query is __schema and its SDL definition is
With this query we can gain information about the directives, available types, and available operation types. The basic introspection query for fetching the type system of the schema might look like this:
However, a lot of fields in the selection sets for queryType, mutationType, subscriptionType and types are the same, so we can define the fragment to have reusable pieces of logic and make the query much cleaner and also enhance selection set to fetch better detail of the type. We can even take fragments used in GraphiQL itself. These fragments look like this:
We can see that GraphiQL is using the fragment TypeRef, which recursively queries the GraphQL schema. This may have some limitations, but the fragment should have enough query depth to cover almost all schemas. We can prevent malicious queries by disabling extra query depth on the GraphQL server. Let’s execute this query to see the whole GraphiQL introspection in use:
As a result, we should obtain the GraphQL schema in JSON format. In our case it is as follows
We can see with this query that we are able to fetch information about all these different features of the schema
When using the introspection query __type we are able to query for the exact type we are interested in. To do so, we are required to specify the argument name of the type. To get full information about a certain type we can use the type fields from above and try to call an introspection query on the type called Planet in our schema. We can reuse the FullType fragment again to save some code, so the query would look like this:
This is the third and last introspection query available. The difference is that this query is available through all types when querying. This shows us what type we are querying and is important for caching clients like Apollo or Relay to construct the cache. Let’s take a look at what happens when we execute it with our Planets query.
We can see that __typename is equal to the name of the type, which in our case is Planet. This is also useful to determine unique ids in caching clients. For example, in the Apollo client we use the
id + __typename
by default for normalization (if both are available) as unique ids to update the cache automatically.
As we have already discussed, introspection queries are mainly used for live documentation of the schema and to create rich IDEs for executing various requests. The most well known IDEs are built on top of GraphiQL. For me personally, I prefer to use GraphQL Playground on big projects, as it has some great additional features such as header definitions for GraphQL requests. Introspection queries can also be used in many different use cases to reduce frontend complexity and to avoid duplicating logic:
- Fetching enum values for drop downs
- Getting all fields for a certain type (great for displaying columns in the table)
- Enumerate all possible interfaces (applicable when making applications that require a lot of abstractions)
More tips on the applications of introspection queries will be available in the Lead Backend Engineer course on GraphQL mastery. To get access to browser exercises on introspection and get more tips on GraphQL, be sure to subscribe to the interest list below for our free GraphQL Language course (coming soon).
You can apply the above queries against any GraphQL schema, which has enabled introspection. Feel free to ask any question about the topic at email@example.com or in comments below.
Originally published at graphqlmastery.com.