GraphQL Queries Part2

This in after previous blog post, lets see more usage of GQL queries

Step1

In the previous blog post, we had structured our queries to return a hard coded response. In this post, we will assume we have two objects for “user” and “address” almost similar to a database structure like mysql and we have multiple user data as well.

P.S I am taking structure similar to a traditional db just so it’s easier to understand, but in real practice graphql works best with nosql db’s

const users = [
    {
        id: 1,
        name : "manish"
    },
    {
        id: 2,
        name : "test"
    },
    {
        id: 3,
        name : "test2"
    }
]

const address = [
    {
        id: 1,
        address : "test",
        country: "IN",
        phone: "000",
        user_id: 1
    },
    {
        id: 2,
        address : "test2",
        country: "IN",
        phone: "2222",
        user_id: 1
    },
    {
        id: 3,
        address : "test3",
        country: "IN",
        phone: "3333",
        user_id: 2
    }
]

Take 2 minutes and understand the above structure, its exactly similar to a mysql database tables called “user” , “address”

https://github.com/nodeexcel/gql_tutorial/commit/2127d8331f017806066422d2f67a1322be4b555f

Step3

Now let’s update our previous profile query and add “id” as well so that we can get profile of a particular user

Our code looks like this now

var queryType = new graphql.GraphQLObjectType({
    name: 'Query',
    fields: {
        profile: {
            type: profileType,
            args: {
                id: { type: graphql.GraphQLInt }
            },
            resolve: (_ ,{ id }) => {
                return users.find((user) => {
                    return user.id == id
                })
            }
        }
    }
});

So, here we see that we are able to pass the parameter to resolve function. Rest is straight forward.

Read more details about this here https://graphql.org/graphql-js/passing-arguments/

Also it’s important to note the arguments that graphql resolve function receives, specifically the first argument which is the root object. Read more about it here https://stackoverflow.com/a/48633592

Step2

Next, we should make the id parameter required as without id our query will not work

args: {
                id: { type: graphql.GraphQLNonNull(graphql.GraphQLInt) }
            },

Step3

Next, we need to return “address” for this particular user only

var profileType = new graphql.GraphQLObjectType({
    name: 'Profile',
    fields: {
        id: {
            type: graphql.GraphQLID
        },
        name: {
            type: graphql.GraphQLString
        },
        address: {
            type: graphql.GraphQLNonNull(new graphql.GraphQLList(addressType)),
            resolve: (user) => {
                return address.filter((addr) => {
                    return addr.user_id == user.id
                })
            }
        }
    }

Notice, the resolve function and first parameter of the function.

https://github.com/nodeexcel/gql_tutorial/commit/6cffb02376e8cc4128b79d0cae5ab58940caf8cb

Cool! Looks good

Step4

At this stage, we have covered most of the basic things related to a GQL Query, next let’s do a bit of code refactoring.

Till now we put everything in a single file, but in a large application this is not viable. Let’s see what is the best way to go about it.

First lets move our schema to different files and data also to a data source file.

Before doing this, we need to install bable etc so that import, export works easily. Use this package.json and do npm install

{
  "scripts": {
    "dev": "nodemon -w src --exec \"babel-node src --presets es2015,stage-0\"",
    "build": "babel src -d dist"
  },
  "dependencies": {
    "express": "^4.16.4",
    "express-graphql": "^0.7.1",
    "graphql": "^14.0.2"
  },
  "devDependencies": {
    "babel-cli": "^6.26.0",
    "babel-preset-env": "^1.7.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "nodemon": "^1.18.9"
  }
}

https://github.com/nodeexcel/gql_tutorial/commit/3f5bd0c124076b578667c991abdbd67bba7b56a4

This is how the code looks after the refactor (ignore the dist/ folder)

Next, we should also move our queries to a separate folder

https://github.com/nodeexcel/gql_tutorial/commit/2e39e26d64fdc2963737cb62a09053f84c8b9ca5

Step5

Now, let’s create multiple “queries” and see how our code looks.

Let’s assume we have a todo app, want to create a query to fetch all todo’s

As soon as we try to do this, we encounter a problem. We have two different schema but how to combine them?

https://github.com/nodeexcel/gql_tutorial/commit/6bd985627023d77808fa048fdcb02e1fc15eee26

see the commit link to understand the issue, we have two schema but no way to merge them.

import profileQuery from './queries/user'
import todoQuery from './queries/todo'

To solve we can use this library https://github.com/okgrow/merge-graphql-schemas or better use apollo graphql-tools

This concept is called “schema stitching” and you can read about it in detail here https://www.apollographql.com/docs/graphql-tools/schema-stitching.html

Before solving the above problem, we need to take a step back and understand from the start graphql-tools library.

excellence-social-linkdin
excellence-social-facebook
excellence-social-instagram
excellence-social-skype