Optimizing and testing GraphQL querying using Node.js and Postman

As GraphQL becomes more and more used in REST APIs as the query language for data fetching, the question of optimal server side data storing is rising. I will demonstrate a simple way of fetching decoupled data using GraphQL and test the average server response time with 1,000,000 objects and 200 requests.

This blog post aims to show the strengths of GraphQL, in a decoupled system, meaning there is no transaction with the database. Data objects are exported in individual files, allowing the system to be highly scalable, and the average server response time to be stable and independent from the file number. Also notice that I run this example locally, so there is no network delay to be taken into consideration.

Installing the modules

The modules used in this example are shown bellow. Express will be used to build our server, express-graphql to create our graphql endpoint, and morgan to log the server response time in the console.

npm install express express-graphql graphql randomstring random-words

GraphQL object type declaration

The returned object for this example has the form of a simple article with an id, a title, and a body. The data is randomly generated.

var servedObjectType = new graphql.GraphQLObjectType({
name: 'servedObject',
fields: function() {
 return {
  id: {
   type: graphql.GraphQLInt
  },
  title: {
   type: graphql.GraphQLString
  },
  body: {
   type: graphql.GraphQLString
  }
 }
}
});

GraphQL query type declaration

The GraphQL query requests the article's id and simply returns the object if found. You can see the declaration bellow:

var queryType = new graphql.GraphQLObjectType({
name: 'Query',
fields: function () {
 return {
  fetchArticle: {
   type: servedObjectType,
   args: {
    id: {type: graphql.GraphQLInt}
   },
   resolve: function (_, { id} ) {
    return JSON.parse(fs.readFileSync(JsonFiles + '/' + id+".json", 'utf8'));
   }
  }
 }
}
});


GraphQL endpoint on the Express server

For this example the endpoint provides an interface for GraphQL querying, accessible from the web browser, this should not be available in production mode, you can change this by setting the "graphiql" value to false.

app.use('/graphql', graphqlHTTP({
schema: graphql.schema,
graphiql: true
}));

Testing with Postman and Newman

As for testing, I generate 1,000,000 articles with dummy data. I also created a simple Node JS module using Newman to make 200 concurrent requests, and presents us with the average server response time in the end. You can view the newman testing script here. Bellow I present a sample of the console log and the average response time.

Node Server Sample Log

POST /graphql 200 3.122 ms - 1081
POST /graphql 200 2.965 ms - 1077
POST /graphql 200 2.168 ms - 1080
POST /graphql 200 1.576 ms - 1082
Newman Node Script Log
*******************************
Test run average: 5.08
*******************************