22

Tl;Dr GraphQL

 4 years ago
source link: https://www.tuicool.com/articles/hit/6NJjQvR
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

QzA3mu3.png!web

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:

[query][query name]{
     typeName {
        fieldName
    }
}

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

Example query:

query getUserName{
    person {
       name 
   }
}

The return result will be something like this

{
  data: {
    person: {
       name: 'Jhon Snow' 
    }
}

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

{
     person {
        name 
    }
}
{
  data: {
    person: {
       name: 'Jhon Snow' 
    }
}

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

{
     person {
        name 
        pet {
          name
       }
    }
}
{
  data: {
    person: {
       name: 'Jhon Snow',
       path: {
          name: 'Doge'
       }
    }
}

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

{
  person(id:'kdlhh123hf3tzf') {
    name
    height (unit: METER)
    pet{
      name
      age(format: DOG_YEARS)
    }
  }
}
{
  data: {
    person: {
       name: 'Jhon Snow',
       # 183 cm
       height: 183
       pet: {
          name: 'Doge',
          age: 7
       }
    }
}

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

query getUsers {
  users(role: admin) {
    id
    firstName
    lastName
    phone
    username
  }
  users(role: accountant) {
    id
    firstName
    lastName
      phone
    username
  }
}

Graphql will give us an error

{
  "errors": [
    {
      "message": "Fields \"users\" conflict because they have differing arguments. Use different aliases on the fields to fetch both if this was intentional.",
      "locations": [
        {
          "line": 2,
          "column": 3
        },
        {
          "line": 9,
          "column": 3
        }
      ]
    }
  ]
}

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

query getUsers {
  admins: users(role: admin) {
    id
    firstName
    lastName
    phone
    username
  }
  accountants: users(role: accountant) {
    id
    firstName
    lastName
    phone
    username
  }
}

the result of this query will be

{
  data: {
    admins: [
      {
        id
        firstName: 'Will'
        lastName: 'Smith'
        phone: '+0912323132'
        username: 'willy'
      }
    ],
    accountants: [
      {
        id
        firstName: 'Hannah'
        lastName: 'Smith'
        phone: '+0912323132'
        username: 'hannah'
      }
    ],
    
  }
}

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

fragment UserInfo on User {
   id
   firstName
   lastName
   phone
   username
}

query getUsers {
  admins: users(role: admin) {
    ...UserInfo
  }
  accountants: users(role: accountant) {
    ...UserInfo
  }
}

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK