Intro : GraphQL

In keeping up with React I have been hearing more and more about GraphQL. I took a couple of hours over the weekend to give it a try. This article covers using just GraphQL without a frontend like React.

GraphQL sells itself as an easier and better REST (which is a discussion in itself). A tool that lets you query for only the data you need. Data is defined by schemas which are created up front in the development process. With schemas defined, developers regardless of their role can get to work without stepping on each others toes.

The basic building block is a schema. Schemas define the shape of data and take on a somewhat JSONish pattern, making them feel familiar. With schemas defined GraphQL then provides mutations based on the schemas. Mutations allow for data creation. With data available, queries can be created and used to fetch data. Fetching data is where GraphQL shines because each query easily defines what the shape of the data returned should look like. Thus highlighting the contrasts between a GraphQL server and a REST API.

Schemas

BudgetUser and Budget are two schemas that will have a many to many relationship. The idea is that a group of users can share the same budget or share multiple budgets with each other. All users contributing and seeing what the others have added to the budget. Now that the functionality is defined and understood, its time to analyze the schemas.

There are some similar attributes that both BudgetUser and Budget have.

createdAt: DateTime!

DateTime is a special value in GraphQL. The system will populate createdAt with the servers current date time. The bang at the end of DateTime means this field is required. When a new entry is created GraphQL will automatically add the systems current DateTime

id: ID! @isUnique

ID will generate a random id composed of alphanumeric values. The @isUnique attribute will make sure each id is unique. Using this on usernames makes sure two users do not have the same username.

type BudgetUser {
...
budgets: [Budget!]! @relation(name: "UserBudgets")
}
type Budget {
...
users: [BudgetUser!]! @relation(name: "UserBudgets")
}

These two lines define the data relationship between these two schemas. Both of these attributes follow the same pattern. The array has a value, that value is required and each array is not nullable. The bang outside of the array is what makes the array not nullable and return an empty array if no values are apart of the entry. The @relation(name: “UserBudgets”) defines the name of the data binding between these two schemas.

With established schemas to work with, the data creation methods within GraphQL are populated.

Mutations

With the schema defined its time to get to the fun stuff. Creating data.

Each mutation gets its own name. createBudgetUser() is a method generated by GraphQL based off the BudgetUser schema previously defined. It takes in the values we want to set for properties within a BudgetUser object. After the createBudgetUser() method define the object that specifies how data will look when returned after GraphQL creates the data. Defining how the data will be formatted in the response body. For this call get the ID back for the user created.

Just like BudgetUser getting its own create method, so does Budget. Using the IDs of the two Users previously created, add them to a new Budget. The budget schema defines an allocation attribute, which in this example is set to 1000. Upon creating this data, the response will just include the newly created Budgets ID.

Quick and easy. Data has been created. The format of the response body has been defined. Not a single endpoint was written. I could get used to this.

Queries

Having a schema not only provides a method for creating data, but it also provides methods for fetching data. Time to write a query.

Here the allBudgets query will return all of the Budgets within the system. The object defined will shape how the returned data will be formatted. allocation will be returned along with all of the users associated with this Budget followed by specific data regarding each user tied to the Budget. Their id and name.

GraphQL by default sets data as the key that will hold all of the response data. Within data GraphQL has a key that is named after the query, in this case allBudgets is an array of Budgets. Four Budgets were created (I created three more other than the one in this article) and the response shows that only the data requested is coming back!

GraphQL

It has been fun learning about GraphQL. This article is such a tip of the iceberg experience with the server. It only covers writing schemas, mutations and queries that works within GraphQL itself. To get an idea of how it works within a framework I also spent some time using GraphQL within React. It was a great experience. It reduced the amount of middleware needed and simplified component data retrieval. It made writing data subscriptions a breeze. All in all, I would love to sink some more time into GraphQL.