Here at Kong, we're advocates for architecting your application as a group of microservices. In this design style, individual services are responsible for handling one aspect of your application, and they communicate with other services within your network to share data. Systems like Kubernetes or the Kuma service mesh help orchestrate traffic and manage network policies so that your microservices can function together as a unified whole.
Communication between microservices is done via an API, a pattern that you're probably familiar with. Your API can be of any protocol—whether that's REST, gRPC or GraphQL. What's important is that you have established a well-defined and consistent format for both your internal needs as well as your external ones.
To test your API (outside of a CI/CD framework), you'll need a client which can make requests to the API. That's why we have Insomnia, an open source client for interacting with APIs. This post and video will show off some of the highlights of using Insomnia as a GraphQL client. We'll build a tiny GraphQL server in Node.js, and then use Insomnia both to fetch and manipulate data on it.
As with any API development process, we'll first need to identify the objects that are necessary for our app. GraphQL has a strongly typed schema defined in a schema definition language (SDL), an idempotent way to describe all the objects and fields available by your GraphQL API.
For our example, we'll create an API that stores and retrieves a list of users, along with their addresses. The beginning of our schema looks like this:
Create a file called schema.graphql, and paste the above lines into it.
To retrieve data from our schema, we need to define an entry point query. For example, our GraphQL query will look something like this:
In this case, we're grabbing a user based on its id, requesting the response to show us that user’s id, name and email.
Queries are also defined in the SDL; the query field belongs to a special reserved type called Query, the main entry point for fetching objects. Add this code to the bottom of your schema.graphql file:
We also want to add a method for updating information. In GraphQL, a query that changes data is called a mutation. For example, a mutation to add a user might look like this:
In SDL, you define the name of the mutation and all the fields that you could use as inputs. Add the following lines to your schema.graphql file:
A schema defines the shape of the stored data and how to construct queries. However, establishing a schema to fit your data model is just one part of the GraphQL server. The other part interacts with data using resolvers. A resolver is just a function that returns the underlying value of a field.
Let’s take a quick look at how our Node server implements resolvers. The intent is to solidify concepts around how resolvers operate in conjunction with schemas, so we won’t go into too much detail around data stores setup.
In the "real world," we might be fetching data through the database. For now, let’s just set up some dummy data. Create a file called server.js and paste these lines into it:
GraphQL resolvers amount to a JSON hash with the key as the name of the field to be retrieved and the value corresponding to a function that returns the data. Let’s start with a barebones example of the initial user lookup by id. Add the following code to the bottom of your server.js file:
This resolver takes two arguments: an object representing the parent (often unused in the initial root query) and a JSON object containing the arguments passed to your field. Not every field will have arguments. In this case, they will because we need to retrieve our user by their id.
Building the API Server
We’ll now use Express to set up a basic API server to provide users GraphQL access to our data. Let's use npm to install the packages our server needs:
Along with the users and resolvers we’ve already added, the rest of our server.js file stands up the server and connects the resolvers with the schema. Add the following code to the bottom of the file:
Run node server.js to boot up the server on port 5000. If you're the cautious type, you can issue a curl command right now to verify that data loads correctly:
The response should be data that corresponds to Francis!
Working With Insomnia GraphQL
Working with curl is acceptable, but it can be cumbersome and limiting. Let's take a look at what Insomnia GraphQL offers.
Basic GraphQL Queries and Mutations
From within the Insomnia dashboard, create a new collection for this project.
From your starting collection screen, click on New Request. Set the HTTP verb to POST and the body to GraphQL. You can also set a name if you desire (here, we chose "GraphQL Sample"). Then, click Create.
Set the URL for your request to your server’s endpoint. Then, copy-paste the query we used earlier into the editor for the GraphQL request body:
Click on "Send." You'll get Francis' data back in an easy-to-read, color-coded format.
Let's try making a mutation next. Paste the following lines into the request body:
In Insomnia, your request will look like this:
Click on "Send." The result shows the newly added record.
For an additional verification that the mutation went through, you can take the returned id (in this case, 3) and perform another getUser query.
The result is our newly added user:
GraphQL Schema Introspection
You can also perform a schema introspection query with Insomnia to give insight into the GraphQL schema undergirding the server. For example, we can learn about the User object and its fields with the following query:
In addition, Insomnia GraphQL can fetch the schema from the server, allowing you to "show documentation:"
The result is an interactive listing where you can drill down through available queries and mutations, seeing object fields and inputs.
Auto-Complete and Suggested Fields
After Insomnia has fetched a schema, future queries and mutations you write have the added help of auto-complete. Query names, required inputs and fields for retrieval are all made available as you type or by pressing cmd/ctrl + space bar.
Plugins for Dynamic Values
Insomnia also supports various plugins for more dynamic testing. For example, we hard-wired the name and email values in our mutation request above. With Insomnia’s faker plugin installed, we can modify our mutation to use a template tag and generate a fake (random) name and email with each request:
The response shows the randomly generated name and email or our new user:
Another useful method for on-the-fly values is using template tags with prompts:
When sending the request, Insomnia will pop up a modal prompting you to enter the value(s) you want to use with your request:
Besides these useful plugins, even more power is available from Insomnia by way of its additional features, including:
The ability to inspect headers
A label indicating how long the entire request/response cycle took
A complete timeline representing the request data, and the server response
These features make it easy to issue GraphQL queries and identify areas to improve your server performance.
Getting More Information on Insomnia GraphQL
Perhaps the greatest strength of Insomnia is the fact that it's completely open source! A large community of developers and backend engineers regularly use and contribute to the project. Insomnia also works for REST and gRPC APIs, providing the same measuring and reporting tools no matter how your server communicates.