visit
This is the second part of my article series on GraphQL Basics. If you haven’t read the previous part you can catch up here.
Last time we finished setting up our basic GraphQL server with Node and Express. We explained why GraphQL exists and what purpose it has, we went through the installation and the basic setup and finished with our first actual query. We’ve learned a lot, but we haven’t done anything practical yet. The feeling of accomplishment when you successfully run a GQL query is great, but it’s power is shown when it comes to more advanced operations. In this article we will look at query parameters and nested queries.
We’ll start by figuring out how to use query parameters and fetch a single entity off our service. In order to fetch data structured in a different manner we will need to add a new field to our RootQuery
. We cannot reuse the posts field that we have for the single post because GraphQL expects it’s type to be a list. But fetching a single item will most likely return an object.
The differences are in the type
and the args
properties. In order for GraphQL to understand what it will receive as params we need to tell it what type they will be. Each of the arguments will be represented as an object with a type. As you can guess GraphQL’s got it’s own magical types that we need to use here. Let’s add two more properties in the destructured list in the beginning of the file.
After that, properties passed in the query will be available to us from the args
object in the resolve
function. Disregard the parentValue
field for now, we’ll discuss it later in the article. Everything else is straight forward — we will use the passed property to query the service for the given post. Because we are again using the post type we needn’t worry about specifying the type fields again. This is how the finished field will look in the RootQuery
In the fetch call I’m using some ES6 wizardry and placing the arguments directly in the strict. Now you can refresh your server (if you’re not using nodemon, which I highly recommend) and run a single post query from the graphical interface.
If everything is done correctly we should see a response containing the data for a single post. Congratulations, this is our first query using parameters! Something interesting to note here is the documentation that GraphQL will automatically create for you. If you look at the right column in the graphical interface you will see a link for the RootQuery. If you click on it you will see all the registered fields that you can query together with their allowed arguments.
We will start by defining a new type — a CommentType
.
Make sure to create it before the PostType
because we will need to reference it there. Once we have it defined, we will need to add a new field on the PostType. This is because by nesting the comments inside of the PostType
, GraphQL will consider it a field.
You have probably noticed that when it comes to fetching resources this is usually done via the resolve function. This is what we did for the post list, for the single post and this is what we will be doing for the comments.
As we mentioned in the previous article, GraphQL acts as a wrapper around the services you use, so in the current case, if we want to fetch posts with their comments we will need to make the two separate requests — GraphQL cannot help us with that. It does however keep the API of the person making the request incredibly clean and simple. With that in mind let’s now define our comments field with a resolve function inside of it to fetch our comments.Here we will finally use the parentValue
property. You will see in a bit that comments are actually a query on their own, so they need to be passed the post id in some way. This is done with the parentValue — it will contain the arguments that are passed to it’s parent query.
You can imagine that it would be a lot easier and intuitive for your front end developer to fetch data like this. Your FE team won’t have to know what service to use or where to fetch data from, since the GraphQL server will serve as a gatekeeper.