Graph theory, structures, and query languages are finding increasing importance in the current technical applications and breakthroughs. The theory and applications both have been around since 1736 since Leonhard Euler published his paper on the Seven Bridges of Königsberg. The most prominent uses of today’s times are social networks, ride-sharing apps like Uber, and food delivery apps.

Graph structure represents the relationships between entities in the form of a network. Each entity is called a node. For example, to constitute the relationship between a husband and a wife, there will be two nodes. Each node will have some information. The relationship between the nodes is called the edge.

Graph Simple Representation

Both the node and the edge can have labels. We have already labeled the nodes. The labels can be numeric, textual, or symbolic. Also, they don’t have to be unique. Both nodes and edges can have attributes.

Since we don’t want to get into the nitty-gritty of the Graph theory, for now, we will shift the gears a bit and start talking about the implementation details.

In the relational databases, relations are defined at the table level, and the related records or nodes are identified by joining the records based on the relationship properties, like employee id and department id. In the graph databases, the relationship is actually between particular nodes. For example, Employee A and Department A will have a direct relationship. So you don’t need joins to identify the related records. The nodes and relationships or edges both can have multiple labels, attributes, and properties, to identify one or more associated nodes. Due to this structure, the issues with JOINs in typical relational databases are avoided with Graph databases. Imagine a query to find the manager of the manager of an employee. You will need a recursive join to do that. Each join will traverse through the entire table to match the required data based on the join conditions. With a graph structure, you don’t need any joins as the relationships are recorded in each node, in this case, for each employee. So you just need to traverse two nodes to find the required information without going through the entire graph. What this means is, the volume of the data will not impact the performance of your queries. Instead, the graph area that you want to cover is what will influence it. For example, if you’re going to find your 3rd or 4th level connections or friends, you will not need to scan the entire tables over and over again, but can travel from one friend to another directly.

As SQL (Structured Query Language) is used for querying data from the relational databases, Graph Query Language (GQL) is used for querying data from graph databases. Neo4J, a graph database, has a GQL Cypher. But now, GQL is going to become the first ISO database language since SQL. A similar alternative is available for APIs too. REST has also been used as the query mechanism for getting the data from APIs. But GraphQL, provides alternate ways to query the data from APIs by conceptualizing and modeling your data as graphs. Facebook has been using it since 2012 and open-sourced the specification in 2015. Since then, it is being used by many leading organizations.

Advantages of GraphQL

With REST, granular control over what and how much data is returned is very difficult for the client. The server decides what data is returned in response to a REST API call, and even if the client does not require that data, the server still sends the entire payload that is defined.

For example, assume that on a particular page, you want to see only the name and birth date of an employee. So you make a GET request with the ID of that employee. But usually, there won’t be any endpoint that just returns the employee name and birthday. More probably, you will get a response containing almost all the fields associated with the employee. Unless you write endpoints for every specific combination of fields you need for the entire application, you will get more data than you need. But writing so many endpoints again is a challenge to the maintainability of the back end.

The composition of the GraphQL queries expresses your data requirements in the same structure as the structure used by the server to return the data. The query is expressed via a hierarchical set of fields. Such an expression is a natural way to show data needs.

The GraphQL is also strongly typed. This provides confidence at the development time that the data will be correctly returned.

 

Okay, so let’s see how to use GraphQL with Node.js, in a basic example below. The entire code can be downloaded from this repository.

Setup

  1. Create the basic express server
  2. Initialize the GraphQL support for express
  3. Define the GraphQL schema, using buildSchema function from the graphql package.
  4. To build the schema, a string with the GraphQL Interface Definition Language (IDL) is created and passed to the buildSchema function.
  5. The schema represents the complete set of data and how clients can access the data. Each client API call will be validated against the schema.
  6. Create a root resolver. This is like routes in a REST API. The resolver defines the mapping between actions and functions. This is similar to how a route invokes associated controller.
  7. Add GraphQL middleware by passing the endpoint you want to use for APIs. The middleware also needs schema and root definition to be passed. You must also set the graphiql parameter to true in order to access an interactive, browser based interface, which can be used to test the GraphQL queries.

 

https://gist.github.com/forwardsprint/878a552d0620cf0b059293a812ae8c3f

Let us create some data for this example. Here is a very simple schema, defined in a file data.json.

 

https://gist.github.com/forwardsprint/d7f486a1cc9f31ca82c074b659976a81

Let’s import the data in the main file.

const data = require(‘./data’);

Our next step is to define the schema.

 

https://gist.github.com/forwardsprint/30eb9702298a0d7249db76d1680ab192

 

As you can see, the schema definition binds the properties and functions of our data entities together. Our “Employee” entity has four properties, id, name, designation, and department. The “query” defines the functions that can be called upon to access the data related to the entity. We are defining two queries, one to get a specific employee with the id passed in the parameters, and second is the list of employees, with the possibility to filter for a particular department. Let’s now see how these queries will be implemented.

 

 

https://gist.github.com/forwardsprint/98f80ea8778ef9bba8794e61d44c62d2

 

getEmployee is a straight forward function. When an employee id is passed to it, it filters the data for that id and returns a single record.

getEmployees function returns a list of employees. We check if the department parameter is passed or not. If it is available, we filter based on the department, and else we return all the employee records.

The next step is to link the queries we defined in the schema to the function we implemented. Think of this as defining the routes in traditional REST APIs. Once we do that, we have all our implemented ready. Let’s connect this to the express server and start it.

https://gist.github.com/forwardsprint/1edc3ce6ba5a3de8875d49e6ba2174d6

Now, when we start our express server, we will have the graphQL apis available.

 

Let’s query our data now.When we access our API, we get a GraphiQL interactive query interface.

 

GraphQL Interface

As you can see from the screenshots, you can send the parameters and the list of data from the clients. With the same endpoint and query definition, you will be able to get the dataset that you need, without having to write any extra code server-side.

 

Mutations

 

Now that we have seen how to implement the read part, let’s quickly see mutations, similar to the POST and PUT requests in a REST API, to add or modify the data. We add the new type Mutation, which defines the parameters and type expected to be received from the client in order to change the data.

https://gist.github.com/forwardsprint/fe051a0801110294ab126abcb4623d7d

 

Then we define how exactly the mutation will work. What data it will change and how. In this function, we are mimicking an auto-increment identified for the new user. We are returning all employees once the mutation is successful. But you can return whatever you want. Typically, the new employee that we added will be returned.

 

https://gist.github.com/forwardsprint/d9a2b513b4af34fc3c7c4c673e3f125c

Here is how the resolver will be modified.

 

https://gist.github.com/forwardsprint/e98f83d3b378238e38b0c68b599ec956

We add the method and GraphQL mutation type to our mapping resolver.

 

GraphQL Interface

Then, you can pass the values for the new user to be added using the query interface.

This article was an initial introduction to implementing GraphQL with Node.js. To learn more about GraphQL itself, check out the GraphQL site. To learn more about the difference between GraphQL and REST, check this article. In the next article on GraphQL, we will talk more about using GraphQL for your applications. Stay tuned.