HomeBack-End & DatabaseGraphQL Queries Part2

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: