Introspection in GraphQL
Yesterday I was asked what my two favorites features about GraphQL are. My answer was Introspection and fetching only the data that you need. Others mentioned the characteristic of being strongly-typed and the easy way to be backward compatible. I was so surprised that no one mentioned introspection, so I decided to talk about what it is and how it is used.
As a developer, we are always consuming new APIs. We often spend a lot of time reading the documentation (frequently out of date) and finding which resources are available. Imagine if the API would provide a tool that tells you which resources you can get/modify and how to do it? It would make things much much easier for the consumer and for developers!
Introspection is the ability to query which resources are available in the current API schema. Given the API, via introspection, we can see the queries, types, fields, and directives it 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. In every server that provides a GraphQL API, we should be able to introspect queries.
The type __Schema is the one that defines the schema the API provides. Its type is defined as the following:
It returns which types the schema has (types), the queryType, the schema’s entry-point for queries, the mutationType, and subscriptionType (similar to queryType but for Mutations and Subscriptions, respectively) the directives available.
To illustrate, let us take a look at this example using the Github API and GraphiQL.
In the left part, we asked for the types defined on the schema, and right part, we got all the types available on the Github API (Try it!), such as User, Actor, Repository, specifying the name, kind, and the description.
The following example shows us the rest of the fields within the __Schema type.
The __type represents the types defined in the system. We can query the type of an object and get its information.
GraphQL supports type name introspection at any point within a query by using the meta‐field
__typename: String!when querying against any Object, Interface, or Union. It returns the name of the object type currently being queried.
Popular clients like Apollo and Relay use this to cache on the client-side. For instance, Apollo generates the cache key of the object based on its
Another topic that comes “for free” by using introspection is deprecations. GraphQL fields indicate whether or not they are deprecated along with their reason.
For developers, GraphQL makes it easy to add a description to each field, deprecate a field and add a reason for deprecation. Additionally, introspection allows developers to create fancy documentation pages or use IDEs like GraphiQL (used in this post) that make it very easy for consumers to browse the documentation.
Although introspection is a huge advantage for developers and consumers, developers must be cautious about what things are “introspectable.” In some cases, we don’t want to expose which types the API provides to everyone. For example, you might expect that non-admin users cannot see administrator actions, so we should hide those functionalities. Another example would be when you’re releasing a feature that you only expose to a certain amount/type of users. There are different approaches to solve this, like using different schemas. GraphQL Ruby gem solved this problem by introducing a new concept called Visibility (See this interesting discussion for more information).
I hope you like this post, and if you are ever asked, “what is the best thing about GraphQL” I hope you have “Introspection” within your options. (If you have any question https://twitter.com/IgnacioChiazzo)