Introduction
In my earlier article, we talked about GraphQL getting popularity replacing REST and did some comparison between those two. In this article, we will build a sample app for GraphQL and see how to create APIs using GraphQL server and client. GraphQL server can be built in NodeJS, Spring, and other supported frameworks. We are going to do that using the express-NodeJS module. Also, there are many clients available for GraphQL like Apollo, Relay, etc.. We will be focusing on Apollo client in this article.
We are going to build an API for Class and Student resources. We will also define some relationships between class and students to see the power of GraphQL. In this example, we will show how a class can have multiple students and can be queried accordingly.
Pre-requisites
- Familiarity with NodeJS and installed on your system
- Any IDE
- Familiarity with ReactJS for client
- A MongoDB database - You can use MongoDB atlas which gives a free account and sufficient for this article.
Set up GraphQL Server
Let's first set up the server that will handle the grphql queries. The server is like an API that will implement the functionality for each graphql query by integrating with DB, third party services, etc...
Step 1 - Set up a Simple NodeJS Application
Create a folder named server. Use npm init command to create a default package.json file in it. Now install some of the basic modules required for this article -
You can also install nodemon module to do the hot deployment.
Step 2 - Setup Express GraphQL
express is a widely used web application framework in NodeJS to create APIs. In this example, we will be using the express-graphql module to handle the graphql query requests. Add the below code in app.js file:
app.listen is used to host this application as an API server and listening to the port 9000.
app.use("/graphql", graphqlHTTP... ) is used to route all the /graphql requests to express-graphql HTTP framework to handle GraphQL queries.

express-graphql also provides a GUI which can be used to test the queries before giving it to Clients. By making graphiql: true, it enables that UI on /graphql path.
Remember to make graphiql:false in production. It is supposed to be used only during development.
The schema field is GraphQLSchema instance and mandatory for graphqlHTTP. We will discuss in Step 4 how to create this schema.
Step 3 - Set up MongoDB Connection
We have used mongoose client here to connect to the MongoDB. However, you can use MongoClient as well. Use the below code to create a connection. Add this code in app.js:
Step 4 - Create MongoDB Schemas
Create Class and Student MongoDB schema so that we can use those to save and retrieve data from collections. An example schema for Class:
Step 5 - Create GraphQL Schema
Create a schema.js file and export it with GraphQLSchema object. There is another schema object called buildSchema as well. But GraphQLSchema is supposed to be better in terms of performance and flexibility.
GraphQL schema has two options for manipulating the data.
- Query - query is used to retrieving the data.
- Mutation - mutation is used to create and update the data records.
There is no direct method to delete the object in GraphQL. It needs to be handled by GraphQL Clients like updateQueries in Apollo. Logic needs to be written to remove the particular object from the list and update the object with updateQueries. There are side effects of this approach as all the cache queries will need to be refetched to sync them with the latest data.
Now, define the queries. A query is a GraphQLObjectType that has names and fields. Let's define the queries:
- retrieve class record based on the Id
- retrieve student record based on the Id
- retrieve all the classes
- retrieve all the students
Each query is like a node in a graph. It will have type, args, and resolve method.
- type - it can be a scalar like an integer, string, etc.. or a GraphQLObjectType.
- args - these are inputs that are used to filter the query results.
- resolve - resolve method defines how to calculate the value for the particular node/object. It can bring data from other services, DB or so. In this case, we are retrieving data from MongoDB collections.
An Example of ClassType that is mentioned in the first query:
Now define mutation :
a mutation is also a GraphQLObjectType and has similar fields. The difference is in the implementation of the resolve method which will save the MongoDB object.
So far, we have created the express-graphql server that can handle the queries and mutation for Class and Student objects. We can test that by using http://localhost:9090/graphql
Set up GraphQL Client
As the server is ready, now let's set up the client. There are many options for GraphQL Clients. We will be using Apollo Client for this example:
Step 1 - Set up React Project
Apollo Client can be used using many languages but React is the most common one. To set up a react app, we would need a create-react-app module. Create the app using the below command:
Step 2- Set up Apollo Client
Import apollo-boost and react-apollo module to create Apolloclient and ApolloProvider objects. ApolloProivder is used to render the content under the React component.
Step 3 - Write Queries
Import gql component from apollo-boost and write graphql compatible queries.
Step 4 - Bind Query Results With React Component
The queries written using gql have to be bound with the React component so that data can be rendered on the UI. For that, we again will be using the react-apollo module.
graphql component will bind the getStudentQuery with StudentList and data will be loaded in props. Using props, we can retrieve each field and render it as a list. Similar code has to be written for AddStudent functionality and bind the mutation query with the react component.
Now, the client is ready and can start the application using the npm start command.
Summary
To Summarize, GraphQL with express is very easy to implement and Apollo client is very much flexible to integrate with the GraphQL server. However, the feature for deleting a record is something missing at the server-side. You need to depend on the GraphQL Clients to provide the feature to handle that but there are side effects of using those solutions as most will try to remove the record from the list, clear all the existing queries' cache and update back to DB.
As usual, the code can be found over Bitbucket- graphql-express
No comments: