GraphQL is a query language for your API. It was open-sourced by Facebook in 2015 and ever since then gained immense popularity as an alternative to REST. Companies like PayPal, Shopify, GitHub, and many other leading companies in tech are using GraphQL today. GraphQL was created to have better communication between the client and the server. In this blog post, we will learn about GraphQL types and how they are used to construct a GraphQL schema.
GraphQL has a strongly typed schema. This means that the schema acts as a contract between the client and the server. This is one of the biggest benefits of using GraphQL.
Scalar types are the primitive data types in GraphQL. Here are the primitive data types that GraphQL supports:
Let’s write a GraphQL object that has its own characteristics, and comprises of items, each with its own type:
type BlogPost { id: ID title: String author: String numberOfLikes: Int }
In the example above, we have created a complex object of type BlogPost. The BlogPost object contains an id, title of the post, author of the post, and the number of likes received. When you write the GraphQL schema, the first thing you’d do is define the types.
Since GraphQL is strongly typed and heavily relies on the types, these are defined at the beginning, before the creation of the schema.
Let’s look at some more types in GraphQL to understand this further.
GraphQL supports the enum type and they work just like how they work in any other programming language. Enums allow you to validate that any argument can have one of the defined values. Enums are also a scalar type in GraphQL.
Here is an example of the enum type in GraphQL:
enum BlogTopics { WEB, MOBILE, FRONTEND, BACKEND, GENERAL }
In the example, we have defined an enum of type BlogTopics. And this enum can have five values. The topics can be web, mobile, frontend, backend, or general. The BlogTopics type is allowed to have any of these five values.
The GraphQL schema supports an extension of the scalar type to have a listen of items. It is as simple as adding square brackets around the type to make it a list of that type. For instance, if you want a list of integers, you can declare it as int which indicates that it is a list type.
Let’s add a list type to our original BlogPost type:
type BlogPost { id: ID title: String author: String numberOfLikes: Int comments: [String] }
We have added an item for blog post comments, and it is a list of strings. This means it could hold multiple comments as a list. Lists are used frequently in GraphQL schema.
A GraphQL schema can contain more than just the scalar types. The two most used types are query and mutation types.
Every GraphQL service will have a query type. This is the entry point to a GraphQL schema. The query in GraphQL represents what the client is asking for from the GraphQL API.
To learn more about GraphQL queries you can read the blog post I wrote detailing how queries are constructed in GraphQL.
Although every GraphQL service has a query type, it may or may not include a mutation type. GraphQL mutations are used to add/update/delete data. The clients can use available mutations to update the data. You can think of it like a POST request in the REST world.
Here is how you define the query and mutation types in the GraphQL schema:
schema { query: Query mutation: Mutation }
In GraphQL, both the query and mutation types are treated just like any other data type.
Let’s look into some examples to understand these better. I am going to extend our previous example of type BlogPost to include a query and mutation type:
type Query { blog_info: [BlogPost] }
In the example above, we have defined a query called blog-info. The query type is defined just like any other type in GraphQL. With this, we have now defined a new query blog-info that the clients can use to retrieve data. It would return an array of data of type BlogPost.
Similarly, we can define mutation types as well:
type Mutation { add_blog_post: (title: String, author: String, numberOfLikes: int) : BlogPost }
Here the add_blog_post mutation can be used to add new items to the BlogPost. It takes in title, author, and numberOfLikes as arguments.
Similarly, you can define several queries and mutations for your GraphQL API.
What’s cool about GraphQL types is that you can define types and decide if they can be nullable or not. I have tweaked our original BlogPost type to include a non-nullable field. Notice below that there is an exclamation mark (!) beside the ID. This indicates that the ID can never be null.
type BlogPost { id: ID! title: String author: String numberOfLikes: Int }
By default, each of the scalar types can be set to null. By adding the exclamation mark we are setting a rule that the field can never be null. I like this feature because it defines a clear contract between the client and the server and eliminates any confusion while using the API.
For more complex schema definitions, we can combine lists and non-nulls in multiple ways. Let’s say you have a list type named [myList]
. Here are the ways you can combine non-null with the list.
[myList!]
. This means that the items within the list cannot be null[myList!]
, with the non-null exclamation mark outside of the square brackets, it means something else. This indicates that null is not accepted but the list is allowed to be empty[mylist!]!
. This is a stricter form of non-null. This means that the list cannot contain any non-null items, and the list cannot be null eitherIn our example below, the comments list cannot have any null items within it:
type BlogPost { id: ID title: String author: String numberOfLikes: Int comments: [String!] }
I hope you enjoyed learning about GraphQL types. If you are interested in further learning about GraphQL and get a big picture overview of GraphQL, you can check out my course on Pluralsight on GraphQL.
Other resources:
If you have any comments, please post your comments below and share this post with your team and friends.
LogRocket is like a DVR for web and mobile apps, recording literally everything that happens on your site. Instead of guessing why problems happen, you can aggregate and report on problematic GraphQL requests to quickly understand the root cause. In addition, you can track Apollo client state and inspect GraphQL queries' key-value pairs.
LogRocket instruments your app to record baseline performance timings such as page load time, time to first byte, slow network requests, and also logs Redux, NgRx, and Vuex actions/state. Start monitoring for free.Would you be interested in joining LogRocket's developer community?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowHandle frontend data discrepancies with eventual consistency using WebSockets, Docker Compose, and practical code examples.
Efficient initializing is crucial to smooth-running websites. One way to optimize that process is through lazy initialization in Rust 1.80.
Design React Native UIs that look great on any device by using adaptive layouts, responsive scaling, and platform-specific tools.
Angular’s two-way data binding has evolved with signals, offering improved performance, simpler syntax, and better type inference.