Introduction to the GraphQL Schema

alexisreina

Alexis Reina

Posted on December 20, 2022

Introduction to the GraphQL Schema

Hi there! In this post we’ll cover some basics concepts to start describing your app data using the GraphQL Schema. But before we dive any further into detail, let’s find out more about GraphQL's origin, motivation and the problems it's conceived to solve.

GraphQL Origins

Before diving into the GraphQL Schema, let's review briefly how GraphQL was originated and what's about. If you want to skip this section, you can go directly to the schema section

A Bit Of History

GraphQL was created at Facebook (Meta) back in 2012, when they were rebuilding their mobile application. When they transitioned to a native app, they needed to build an API for their news feed from scratch.

After considering many alternatives -including REST- they decided to start a new project, that later would become GraphQL.

We were frustrated with the differences between the data we wanted to use in our apps and the server queries they required. We don’t think of data in terms of resource URLs, secondary keys, or join tables; we think about it in terms of a graph of objects and the models we ultimately use in our apps like NSObjects or JSON

GraphQL was designed to reduce the code needed to prepare and process the data needed both in the frontend and the backend, to bring data-fetching closer to the perspective of product owners and developers.

GraphQL was our opportunity to rethink mobile app data-fetching from the perspective of product designers and developers. It moved the focus of development to the client apps, where designers and developers spend their time and attention.

Three years later the project was open-sourced. Now maintained by a large community of companies and individuals from all over the world.

Today, GraphQL is used in production by lots of different companies such as Airbnb, GitHub, Shopify or Coursera - to name a few.

So, What Exactly is GraphQL?

GraphQL is both a query language and a server-side runtime to fulfill those queries using a type system (schema) you define for your data.

It's an alternative to REST designed to make APIs fast and flexible, providing a complete description of the data, allowing the clients to request exactly what they need.

Github GraphQL Explorer

At its core, a GraphQL query is just a string that is sent to a server to be interpreted and fulfilled, which then returns JSON back to the client.

The GraphQL server exposes a single endpoint and responds with just the data the client asked for.

As we can see the shape of the query closely resembles the response, but how can we know what data and fields can we query for?

GraphQL Schema Definition Language (SDL)

GraphQL is agnostic to the data sources or programming language, in fact there are many implementations in different languages.

Instead GraphQL has its own type system that’s used to define the schema of an API. The syntax for writing schemas is called Schema Definition Language (SDL).

The schema is used to define a collection of types and the relationships between them, but it’s not responsible for defining how the data it's stored or where it comes from.

Queries, Mutations and Subscriptions

In GraphQL there're 3 special object types already predefined for us, that will act as the entry point to our schema and app.

  • Query are used for fetching data from our server.
  • Mutation used for requesting data modifications.
  • Subscription used for notifying your client in real time about changes to back-end data.
type Query {
  albums: [Album!]!
}
Enter fullscreen mode Exit fullscreen mode

As we can see in the example, our albums query will return a list of Album. But what is an Album?

Object Types

Objects and fields are the nuts-and-bolts of any GraphQL Schema. Following with our previous example, lets now define our Album object.

type Album {
  id: ID!
  title: String
  author: Author!
  photos: [Photo]
}
Enter fullscreen mode Exit fullscreen mode

Let’s stop for a second and review what we have here:

  • Album is an Object Type which contain fields.
  • title is a field of our Album.
  • Its value String, is a built-in Scalar Type and represent the type title will resolve to.
  • Note that we also have 2 other fields, author and photo that point to 2 other object types.
  • Author is another object type which we will define in a moment.
  • And [Photo] a List Type and represent an array of objects.

Adding an exclamation mark at the end of field types like String! or Author! means that the field is non-nullable and that you can always expect to receive a value when the field is queried.

It's possible to make nested lists [[Matrix]] and make list non-nullable using exclamation marks like [Photo!]!.

In order to complete our schema, let's define next our Photo and Author types.

type Photo {
  id: ID!
  title: String
  url: String!
  thumbnailUrl: String!
  album: Album
}

type Author {
  id: ID!
  name: String!
  email: String
  albums: [Album]
}
Enter fullscreen mode Exit fullscreen mode

Scalar Types

Scalar types represent concrete data. In the GraphQL SDL we have 5 built-in scalar types:

  • Int: A signed 32‐bit integer.
  • Float: A signed double-precision floating-point value.
  • String: A UTF‐8 character sequence.
  • Boolean: true or false.
  • ID: The ID scalar type represents a unique dentifier. It will be serialized as a string and be used by client libraries for caching.

Besides these basic types, most GraphQL libraries will allow you to define custom types, such as Date or Json.

Enumeration Types

Enumeration types are a special kind of scalars that are restricted to a particular set of allowed values.

For example, we could express some measure units using an enum instead of the generic scalar String.

enum Unit { 
  INCHES 
  CENTIMETERS 
} 

type Distance { 
  unit: Unit! 
  amount: Float! 
}
Enter fullscreen mode Exit fullscreen mode

Enums values are normally expressed using all-caps. They are very useful to validate arguments, keep data values consistent and communicate through our type system that a field will always be one of a finite set of values.

Note that the implementation of GraphQL enums are specific to the language in which our service is implemented.

Arguments and Input Objects

Every field on a GraphQL object can have zero or any number of arguments.

type Query {
  albums(ids: [ID]): [Album!]!
}
Enter fullscreen mode Exit fullscreen mode

Arguments in GraphQL are passed by name. In this case, we just added ids to our albums field. They can be either required or optional.

It's possible define a default value that will be used when the value of that argument is not explicitly passed.

When we want our arguments to be complex objects we need to use the input type.

input PaginationInput {
  limit: Int = 10
  offset: Int = 0
}

type Query { 
  albums(ids: [ID], pagination: PaginationInput): [Album!]!
}
Enter fullscreen mode Exit fullscreen mode

Also be aware that inputs, unlike object types, can't have arguments in their fields and can be made only of scalar types and other input types.

Please note that the snippet above is an incomplete example of how to implement the pagination of a query and it's only used to illustrate the use of inputs.

Unions and Interfaces

Unions and interfaces are both abstract types that allow a field to have multiple object types.

Let's explore them with an example. Let's create 2 different types of books first.

type TextBook { 
  id: ID! 
  brand: String! 
  price: Float
}

type NoteBook { 
  id: ID! 
  brand: String! 
  price: Float
} 
Enter fullscreen mode Exit fullscreen mode

Now let's create a quey that returns either one or the other depending on the id we pass to it.

union Book = TextBook | NoteBook 

type Query { 
  book(id: ID!): Book 
}  
Enter fullscreen mode Exit fullscreen mode

Note that members of a union type need to be concrete object types. It's not possible to create a union type out of interfaces or other unions.

Now let's explore how to express the same but this time using interfaces.

interface Book { 
  id: ID! 
  brand: String! 
  price: Float
}

type TextBook implements Book {
  id: ID!
  brand: String!
  price: Float
}

type NoteBook implements Book {
  id: ID! 
  brand: String! 
  price: Float 
}

type Query {
  book(id: ID!): Book
}
Enter fullscreen mode Exit fullscreen mode

As we can see an interface declares a set of fields that multiple objects must include to implement it.

Wrapping it up

Thank you for making it all the way here, to the end of this post. Today we have explored the building blocks of the GraphQL schema and hopefully after reading this post you're now better prepared to create your own GraphQL service.

As we've seen the GraphQL schema is one of the main elements of the GraphQL spec, enabling some advantages compared to other data fetching making possible to have a hierarchical, declarative and strongly-typed backend API.

If you want to start playing around with GraphQL queries without having to write your own service, I'd recommend you using the Github GraphQL Explorer.

And that's it for now! Please let me know in the comments what do you think about this post and about GraphQL? Would you like to know more about directives, fragments, resolvers and dataloaders? If so, leave a comment below. Thank you so much for reading!

References

https://engineering.fb.com/2015/09/14/core-data/graphql-a-data-query-language/

https://spec.graphql.org/October2021/

https://graphql.org

https://www.howtographql.com

https://www.redhat.com/en/topics/api/what-is-graphql

https://www.prisma.io/blog/graphql-sdl-schema-definition-language-6755bcb9ce51

https://www.digitalocean.com/community/tutorials/graphql-graphql-sdl

https://www.apollographql.com/docs/react/data/subscriptions/

https://blog.logrocket.com/what-you-need-to-know-about-graphql-enums/

https://daily.dev/blog/pagination-in-graphql

https://www.optisolbusiness.com/insight/top-5-advantages-of-graphql

https://apiacademy.co/2022/05/key-use-cases-for-graphql-apis/

💖 💪 🙅 🚩
alexisreina
Alexis Reina

Posted on December 20, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related