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.