Introduction to the GraphQL Schema
Tags: graphql, beginners, webdev, tutorial
Published: 2022-12-20 09:07:46

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](#sdl)

### 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](https://engineering.fb.com/2015/09/14/core-data/graphql-a-data-query-language/), 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](https://landscape.graphql.org/borderless-mode?grouping=category) 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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y4at12u19udvs1akihfg.png)

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?

<h2 id="sdl">GraphQL Schema Definition Language (SDL)</h2>

GraphQL is agnostic to the data sources or programming language, in fact [there are many implementations](https://graphql.org/code/) 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](https://www.digitalocean.com/community/tutorials/graphql-graphql-sdl) (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.

```graphql
type Query {
  albums: [Album!]!
}
```

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.

``` graphql
type Album {
  id: ID!
  title: String
  author: Author!
  photos: [Photo]
}
```

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.

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

type Author {
  id: ID!
  name: String!
  email: String
  albums: [Album]
}
```

### 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`.

``` graphql 
enum Unit { 
  INCHES 
  CENTIMETERS 
} 

type Distance { 
  unit: Unit! 
  amount: Float! 
}
```

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.

``` graphql 
type Query {
  albums(ids: [ID]): [Album!]!
}
```

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**.

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

type Query { 
  albums(ids: [ID], pagination: PaginationInput): [Album!]!
}
``` 

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.

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

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

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

```graphql 
union Book = TextBook | NoteBook 

type Query { 
  book(id: ID!): Book 
}  
``` 

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**.

``` graphql  
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
}
```

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](https://www.javatpoint.com/graphql-advantages-and-disadvantages) 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](https://docs.github.com/en/graphql/overview/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/