Khaled Garbaya

Engineering Leader, Software Developer & Educator

Tl;Dr GraphQL

What is GraphQL?

GraphQL is a query language for Your API, and a server-side runtime for executing your queries. It is not tied to any specific database engine it is up to you to resolve the query. To create a GraphQL service you define types and their fields, then provide functions for each field on each type.

GraphQL query language

A GraphQL query looks like this:

1[query][query name]{ 2 typeName { 3 fieldName 4 } 5} 6

Everything inside the square brackets, [ and ] is optional.

Example query:

1query getUserName{ 2 person { 3 name 4 } 5} 6

The return result will be something like this

1{ 2 data: { 3 person: { 4 name: 'Jhon Snow' 5 } 6} 7

Fields

GraphQL is about asking your service for specific fields from specific objects. For example: getting the name field from a user. The nice thing about GraphQL is the data you get is shaped exactly as the query.

change this to table side by side

1{ 2 person { 3 name 4 } 5} 6
1{ 2 data: { 3 person: { 4 name: 'Jhon Snow' 5 } 6} 7

A field can also refer an Object or a collection of Objects, for example let say every person in the database can have a pet. The query will look like this: change this to table side by side

1{ 2 person { 3 name 4 pet { 5 name 6 } 7 } 8} 9
1{ 2 data: { 3 person: { 4 name: 'Jhon Snow', 5 path: { 6 name: 'Doge' 7 } 8 } 9} 10

Arguments

In GraphQL every field and nested object can get its own set of arguments, this is very powerful, and sets GraphQL from REST apart.

So let's evolve our previous query a bit

1{ 2 person(id:'kdlhh123hf3tzf') { 3 name 4 height (unit: METER) 5 pet{ 6 name 7 age(format: DOG_YEARS) 8 } 9 } 10} 11
1{ 2 data: { 3 person: { 4 name: 'Jhon Snow', 5 # 183 cm 6 height: 183 7 pet: { 8 name: 'Doge', 9 age: 7 10 } 11 } 12} 13

Let me explain the previous query. I told my service to get the user with the id kdlhh123hf3tzf with the fields name and the height in meter. Using arguments you can specify things like the format of the field.

Aliases

Let's take this example query

1query getUsers { 2 users(role: admin) { 3 id 4 firstName 5 lastName 6 phone 7 username 8 } 9 users(role: accountant) { 10 id 11 firstName 12 lastName 13 phone 14 username 15 } 16} 17

Graphql will give us an error

1{ 2 "errors": [ 3 { 4 "message": "Fields \"users\" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.", 5 "locations": [ 6 { 7 "line": 2, 8 "column": 3 9 }, 10 { 11 "line": 9, 12 "column": 3 13 } 14 ] 15 } 16 ] 17} 18

That's because we can't use the same node name twice similar to json. To solve that we can use GraphQL Aliases.

1query getUsers { 2 admins: users(role: admin) { 3 id 4 firstName 5 lastName 6 phone 7 username 8 } 9 accountants: users(role: accountant) { 10 id 11 firstName 12 lastName 13 phone 14 username 15 } 16} 17

the result of this query will be

1{ 2 data: { 3 admins: [ 4 { 5 id 6 firstName: 'Will' 7 lastName: 'Smith' 8 phone: '+0912323132' 9 username: 'willy' 10 } 11 ], 12 accountants: [ 13 { 14 id 15 firstName: 'Hannah' 16 lastName: 'Smith' 17 phone: '+0912323132' 18 username: 'hannah' 19 } 20 ], 21 22 } 23} 24

Fragments

A graphql auery can get very verbose and Mainly because you need to provide every field you want to pull from your graphql endpoint. Using Graphql Fragment you can reuse pieces of query logic accross multiple queries. We can improve our previous query using fragment like this

1fragment UserInfo on User { 2 id 3 firstName 4 lastName 5 phone 6 username 7} 8 9query getUsers { 10 admins: users(role: admin) { 11 ...UserInfo 12 } 13 accountants: users(role: accountant) { 14 ...UserInfo 15 } 16} 17

What happened here is that we groupped the common fields on the User Object in a Fragment and we used it everytime we query for a user instead of writing the field names over and over again.

Where to go from here

Next one in your inbox

no spam only content