{"id":17491,"date":"2023-02-17T09:03:38","date_gmt":"2023-02-17T14:03:38","guid":{"rendered":"https:\/\/qxf2.com\/blog\/?p=17491"},"modified":"2023-02-17T09:05:03","modified_gmt":"2023-02-17T14:05:03","slug":"virtualizing-graphql-microservice","status":"publish","type":"post","link":"https:\/\/qxf2.com\/blog\/virtualizing-graphql-microservice\/","title":{"rendered":"Virtualizing GraphQL Microservice using Apollo Server"},"content":{"rendered":"<p>There is plenty of information online about how to virtualize REST based microservices. At our clients, <a href=\"https:\/\/qxf2.com\/?utm_source=ApolloServer&#038;utm_medium=click&#038;utm_campaign=From%20blog\">Qxf2<\/a> has implemented different techniques like using a Flask app, using wiremock, etc. But recently we found the need to for virtualizing a GraphQL microservice to expand the scope of our test automation on our CI environment. In this post, we will show one way to virtualize a GraphQL based microservice. In theory, the approach is very similar to mocking a REST API. However, there are enough implementation differences that we thought it was worth explaining at length in a blog post.<\/p>\n<h4>Why use service virtualization for testing?<\/h4>\n<p>At Qxf2, we are big fans of service virtualization as a testing technique. This is because it allows us to isolate the application under test from any third-party dependencies it may have. By doing so, we can enable developers to test the application on their local machines, and also ensure that most integration tests run smoothly with the CI setup.<br \/>\nMoreover, service virtualization can help reduce the costs associated with testing. This is because it means we need to use and maintain fewer third-party licenses in our test environments. Furthermore, it enables us to test a wider range of possibilities, such as how the application behaves when a third-party dependency is slow or (even worse) down.<\/p>\n<p>In this post, we will demonstrate how to virtualize a GraphQL microservice. Specifically, we will show you how to create a sandbox GraphQL server that mocks the responses for the queries. To start, we will show you how to mock a single query and then extend the example to show how we mocked authentication. Once you have learned this, you can easily extend the example to mock all the queries you need.<\/p>\n<h4> Ways to Virtualize GraphQL Microservices<\/h4>\n<p>There are several options when it comes to virtualizing GraphQL microservices. There are many tools like <strong>mocki.io<\/strong>, <strong>mountebank<\/strong>, <strong>json-graphql-server<\/strong> etc, which allows us to easily mock GraphQL servers. These tools make it quick and easy to get started with mocking simple GraphQL interfaces. However, we needed more fine-grained control over the data that is needed to be returned. So, in our example we will be using <a href=\"https:\/\/www.npmjs.com\/package\/@apollo\/server\" rel=\"noopener\" target=\"_blank\">Apollo server<\/a> and <a href=\"https:\/\/www.npmjs.com\/package\/@graphql-tools\/mock\" rel=\"noopener\" target=\"_blank\">@graphql-tools\/mock<\/a> node packages to setup our own sandbox GraphQL server that mocks the <strong><a href=\"https:\/\/github.com\/qxf2\/qxf2-employees\">qxf2-employees<\/a><\/strong> microservices, which is used by the <strong><a href=\"https:\/\/github.com\/qxf2\/qxf2-survey\" rel=\"noopener\" target=\"_blank\">qxf2-survey<\/a><\/strong> app to retrieve the employee details.<\/p>\n<h3>Overview<\/h3>\n<p>Since this is going to be a long post, here is a quick overview of what we will cover:<br \/>\nA. Pre-requisites<br \/>\nB. Getting Started<br \/>\nC. Setting Up a Virtual GraphQL Server<br \/>\nD. Defining the Schema<br \/>\nE. Mocking the response for the queries<br \/>\nF. Mocking the Authentication<br \/>\nF1. Mocking the generation of tokens<br \/>\nF2. Validation of tokens in the header<br \/>\nG. Putting it all together<\/p>\n<p>We will be mocking the response returned for the following query:<\/p>\n<pre lang=\"graphql\">\r\nquery findAllEmployees {\r\n  allEmployees {\r\n    edges {\r\n      node {\r\n        email\r\n        employeeId\r\n        dateJoined\r\n        isActive\r\n        blogAuthorName\r\n        firstname\r\n        lastname\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>In addition, we will demonstrate how to mock the authentication process, which includes generating an access token and validating the authorization headers.<\/p>\n<h4>A. Pre-requisites<\/h4>\n<p>You need to have at least <strong>Nodejs<\/strong> version 14 or above and <strong>npm<\/strong> installed on your machine. You can refer to <a href=\"https:\/\/nodejs.org\/en\/download\/package-manager\/\">the following link<\/a> if needed. <\/p>\n<h4>B. Getting Started<\/h4>\n<p>1. To start off, we&#8217;ll initialize a new project by running the following command in the terminal:<\/p>\n<pre lang=\"javascript\">\r\nnpm init -y\r\n<\/pre>\n<p>This creates a default <code>package.json<\/code> file for your project, which contains information about the project and its dependencies.<\/p>\n<p>2. Next, we&#8217;ll install the necessary libraries to build our GraphQL server.  Use the following command to install the dependencies:<\/p>\n<pre lang=\"javascript\">\r\n npm install --save @apollo\/server @graphql-tools\/mock dotenv graphql graphql-tools\r\n<\/pre>\n<p>3. Finally, create a new JavaScript file in your project. Let&#8217;s name it <code><em>mock-graphql-server.js<\/em><\/code> for this example.<br \/>\nYou&#8217;re now ready to begin building your own virtual GraphQL server!<\/p>\n<h4>C. Setting Up a Virtual GraphQL Server<\/h4>\n<p>The first step in virtualizing a GraphQL microservice is to set up a virtual GraphQL server. This can be accomplished using the <code>ApolloServer<\/code> library in <strong>Node.js<\/strong>.<br \/>\n1. Let&#8217;s begin by importing the required libraries. The <code>ApolloServer<\/code> library is imported from the <code>@apollo\/server package<\/code>, and the <code>startStandaloneServer<\/code> method is imported from the <code>@apollo\/server\/standalone<\/code> package.<\/p>\n<pre lang=\"javascript\">\r\nconst { ApolloServer } = require('@apollo\/server');\r\nconst { startStandaloneServer } = require('@apollo\/server\/standalone');\r\n<\/pre>\n<p>2. Next, we declare our sample <strong>typeDefs<\/strong> and <strong>resolvers<\/strong>.<\/p>\n<li><strong>typeDefs<\/strong> is a string that represents the GraphQL schema of our server.<\/li>\n<li><strong>resolvers<\/strong> are used to handle the responses that are returned for data requests made by GraphQL queries.<\/li>\n<p>Let&#8217;s define a query &#8220;reslove_me&#8221; under <code>typeDef<\/code> which would be resolved to give response &#8220;Resolved&#8221;<\/p>\n<pre lang=\"javascript\">\r\nconst typeDefs = `\r\n  type Query {\r\n    resolve_me: String\r\n  }`;\r\nconst resolvers = {\r\n    Query: {\r\n      resolve_me: () => 'Resolved',\r\n    },\r\n  };\r\n<\/pre>\n<p>3. Now we will use the  <code>ApolloServer<\/code> class to create a new instance of the virtual GraphQL server. The <code>typeDefs<\/code> and <code>resolvers<\/code> needs to be passed as options to the constructor.<\/p>\n<pre lang=\"javascript\">\r\nconst server = new ApolloServer({\r\n  typeDefs,\r\n  resolvers,\r\n});\r\n<\/pre>\n<p>4. Finally, we can define the code to start our server by calling the <code>startStandaloneServer()<\/code> method. Here, you can also specify the port you want your server to run on, by default the port is  set to 4000.<\/p>\n<pre lang=\"javascript\">\r\nconst server_port = 5000\r\nconst { url } = startStandaloneServer(server, {listen: { port: server_port }});\r\nconsole.log(`\ud83d\ude80 Server listening at Port: ${server_port}`);\r\n<\/pre>\n<p>5. Your complete code should look similar to this:<\/p>\n<pre lang=\"javascript\">\r\nconst { ApolloServer } = require('@apollo\/server');\r\nconst { startStandaloneServer } = require('@apollo\/server\/standalone');\r\nconst typeDefs = `\r\n  type Query {\r\n    resolve_me: String\r\n  }`;\r\nconst resolvers = {\r\n    Query: {\r\n      resolve_me: () => 'Resolved',\r\n    },\r\n  };\r\n\r\nconst server = new ApolloServer({\r\n  typeDefs,\r\n  resolvers,\r\n});\r\n\r\nconst serverPort = 5000;\r\nconst { url } = startStandaloneServer(server, { listen: { port: serverPort } });\r\nconsole.log(`\ud83d\ude80 Server listening at Port: ${serverPort}`);\r\n<\/pre>\n<p>6. You can now run your code using <code>node mock-graphql-server<\/code>.<\/p>\n<p>7. Open your browser and navigate to http:\/\/localhost:5000\/. You should see a GraphQL web interface.<br \/>\n<figure id=\"attachment_17580\" aria-describedby=\"caption-attachment-17580\" style=\"width: 900px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/sandbox_server.jpg\" data-rel=\"lightbox-image-0\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/sandbox_server-1024x538.jpg\" alt=\"Web interface for Apollo server GraphQL server\" width=\"900\" height=\"473\" class=\"size-large wp-image-17580\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/sandbox_server-1024x538.jpg 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/sandbox_server-300x158.jpg 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/sandbox_server-768x403.jpg 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/sandbox_server-1536x807.jpg 1536w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/sandbox_server.jpg 1763w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption id=\"caption-attachment-17580\" class=\"wp-caption-text\">GraphQL web interface by Apollo Server<\/figcaption><\/figure><\/p>\n<p>8. Try running the query: <\/p>\n<pre lang=\"graphql\">query resolver{resolve_me}<\/pre>\n<p>9. You should see the following response:<\/p>\n<pre lang=\"graphql\">\r\n{\r\n  \"data\": {\r\n    \"resolve_me\": \"Resolved\"\r\n  }\r\n}\r\n<\/pre>\n<p>As mentioned earlier, if you look back at our code, you would see that we have defined a <code>resolver<\/code> which returns a string &#8220;Resolved&#8221; when the query &#8220;resolve_me&#8221; is called. <\/p>\n<p>Pretty cool right? Now lets go ahead and replace the sample Query in <code>typeDef<\/code> and define the actual schema we are trying to mock.<\/p>\n<h4>D. Defining the Schema<\/h4>\n<p>We define our GraphQL schema using the GraphQL type system. The schema is a blueprint for what kind of data can be requested from the API. In our case, we have to mock the following Query: <\/p>\n<pre lang=\"graphql\">\r\nquery findAllEmployees {\r\n  allEmployees {\r\n    edges {\r\n      node {\r\n        email\r\n        employeeId\r\n        dateJoined\r\n        isActive\r\n        blogAuthorName\r\n        firstname\r\n        lastname\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>1. We can do this by defining a Query type that includes the <code>allEmployees<\/code> field.<\/p>\n<pre lang=\"javascript\">\r\nconst typeDefs = `#graphql\r\n  type Query {\r\n    allEmployees: Employees\r\n  }\r\n<\/pre>\n<p>You would notice that <code>allEmployees<\/code> is of  a custom type <code>Employees<\/code>.<\/p>\n<p>2. Now lets define the custom type <code>Employees<\/code><\/p>\n<pre lang=\"javascript\">\r\n  type Employees {\r\n    edges: [EmployeeEdge]\r\n  }\r\n<\/pre>\n<p>The type <code>Employees<\/code> has a single field <code>edges<\/code> which is an array of another custom type <code>EmployeeEdge<\/code><\/p>\n<p>3. Let&#8217;s define the <code>EmployeeEdge<\/code> type<\/p>\n<pre lang=\"javascript\">\r\n  type EmployeeEdge {\r\n    node: Employee\r\n  }\r\n<\/pre>\n<p>The <code>EmployeeEdge<\/code> type consists of the field <code>node<\/code> which is of another custom type <code>Employee<\/code><\/p>\n<p>4. Finally, lets define the type <code>Employee<\/code><\/p>\n<pre lang=\"javascript\">\r\n  type Employee {\r\n    email: String\r\n    employeeId: String\r\n    dateJoined: String\r\n    isActive: String\r\n    blogAuthorName: String\r\n    firstname: String\r\n    lastname: String\r\n  }\r\n<\/pre>\n<p>As you can see the custom type <code>Employee<\/code> has several fields of the type &#8216;<strong>String<\/strong>&#8216;<\/p>\n<p>5. Our <code>typeDef<\/code> should now look similar to this:<\/p>\n<pre lang=\"javascript\">\r\nconst typeDefs = `#graphql\r\n  type Query {\r\n    allEmployees: Employees\r\n  }\r\n  type Employees {\r\n    edges: [EmployeeEdge]\r\n  }\r\n\r\n  type EmployeeEdge {\r\n    node: Employee\r\n  }\r\n  type Employee {\r\n    email: String\r\n    employeeId: String\r\n    dateJoined: String\r\n    isActive: String\r\n    blogAuthorName: String\r\n    firstname: String\r\n    lastname: String\r\n  }\r\n`;\r\n<\/pre>\n<p>6.  With this schema, a client can query for all employees by sending the GraphQL query mentioned above<br \/>\nNext, lets take a look at how we can resolve this query and return response for it<\/p>\n<h4>E. Mocking the response for the queries<\/h4>\n<p>I mentioned earlier that we could resolve the queries by defining a resolver. But in this case <code>allEmployees<\/code> is of a custom type and defining a resolver can be tedious. So, let us use the magic of <code>@graphql-tools\/mock<\/code> to generate a mock response for the query.<\/p>\n<p>1. To do this lets first import the <code>addMocksToSchema<\/code> library from package <code>@graphql-tools\/mock<\/code> and library <code>makeExecutableSchema<\/code> from <code>@graphql-tools\/schema<\/code> <\/p>\n<pre lang=\"javascript\">    \r\nconst { addMocksToSchema } = require ('@graphql-tools\/mock');\r\nconst { makeExecutableSchema } =  require('@graphql-tools\/schema');\r\n<\/pre>\n<p>2. Next, replace the existing server with the following:<\/p>\n<pre lang=\"javascript\">    \r\nconst server = new ApolloServer({\r\n    schema: addMocksToSchema({\r\n      schema: makeExecutableSchema({ typeDefs, resolvers }),\r\n      preserveResolvers: true,\r\n    }),\r\n  });\r\n<\/pre>\n<p><code>addMocksToSchema<\/code> automatically generates mock data for the fields in a GraphQL schema.<br \/>\n3. Our final code should look similar to this:<\/p>\n<pre lang=\"javascript\">   \r\nconst { ApolloServer } = require('@apollo\/server');\r\nconst { startStandaloneServer } = require('@apollo\/server\/standalone');\r\nconst { addMocksToSchema } = require ('@graphql-tools\/mock');\r\nconst { makeExecutableSchema } =  require('@graphql-tools\/schema');\r\n\r\nconst typeDefs = `#graphql\r\n  type Query {\r\n    allEmployees: Employees\r\n  }\r\n  \r\n  type Employees {\r\n    edges: [EmployeeEdge]\r\n  }\r\n\r\n  type EmployeeEdge {\r\n    node: Employee\r\n  }\r\n\r\n  type Employee {\r\n    email: String\r\n    employeeId: String\r\n    dateJoined: String\r\n    isActive: String\r\n    blogAuthorName: String\r\n    firstname: String\r\n    lastname: String\r\n  }\r\n`;\r\n\r\nconst resolvers = {\r\n    Query: {},\r\n  };\r\n\r\nconst server = new ApolloServer({\r\n    schema: addMocksToSchema({\r\n      schema: makeExecutableSchema({ typeDefs, resolvers }),\r\n      preserveResolvers: true,\r\n    }),\r\n  });\r\n\r\nconst server_port = 5000\r\nconst { url } = startStandaloneServer(server, {listen: { port: server_port }});\r\n  \r\nconsole.log(`\ud83d\ude80 Server listening at Port: ${server_port}`);\r\n<\/pre>\n<p>4. Now, run the script again  navigate to http:\/\/localhost:5000\/ and run the query:<\/p>\n<pre lang=\"graphql\">\r\nquery findAllEmployees {\r\n  allEmployees {\r\n    edges {\r\n      node {\r\n        email\r\n        employeeId\r\n        dateJoined\r\n        isActive\r\n        blogAuthorName\r\n        firstname\r\n        lastname\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>5. You should see the following response:<\/p>\n<pre lang=\"graphql\">\r\n{\r\n  \"data\": {\r\n    \"allEmployees\": {\r\n      \"edges\": [\r\n        {\r\n          \"node\": {\r\n            \"email\": \"Hello World\",\r\n            \"employeeId\": \"Hello World\",\r\n            \"dateJoined\": \"Hello World\",\r\n            \"isActive\": \"Hello World\",\r\n            \"blogAuthorName\": \"Hello World\",\r\n            \"firstname\": \"Hello World\",\r\n            \"lastname\": \"Hello World\"\r\n          }\r\n        },\r\n        {\r\n          \"node\": {\r\n            \"email\": \"Hello World\",\r\n            \"employeeId\": \"Hello World\",\r\n            \"dateJoined\": \"Hello World\",\r\n            \"isActive\": \"Hello World\",\r\n            \"blogAuthorName\": \"Hello World\",\r\n            \"firstname\": \"Hello World\",\r\n            \"lastname\": \"Hello World\"\r\n          }\r\n        }\r\n      ]\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>All the fields in the response are magically populated!!<\/p>\n<p>6. But, in my case I want to return a specific response for each field rather than &#8220;Hello World&#8221;. We can do this by passing the desired mock data to the <code>addMocksToSchema<\/code> method<\/p>\n<p>7. First lets create the data that we would like to return. For this example lets add the details of two employees &#8216;<code>smart learner<\/code>&#8216; and &#8216;<code>slow learner<\/code>&#8216; and assign it to a variable <strong>employees<\/strong>:<\/p>\n<pre lang=\"javascript\">    \r\nlet employees = [ \r\n    {\r\n        \"email\": \"smart_learner@qxf2.com\",\r\n        \"employeeId\": \"4\",\r\n        \"dateJoined\": \"04-Sept-1976\",\r\n        \"isActive\": \"Y\",\r\n        \"blogAuthorName\": \"user4\",\r\n        \"firstname\": \"Smart\",\r\n        \"lastname\": \"Learner\"\r\n    },\r\n\r\n    {\r\n        \"email\": \"slow_learner@qxf2.com\",\r\n        \"employeeId\": \"5\",\r\n        \"dateJoined\": \"25-Feb-1977\",\r\n        \"isActive\": \"Y\",\r\n        \"blogAuthorName\": \"user3\",\r\n        \"firstname\": \"Slow\",\r\n        \"lastname\": \"Learner\"\r\n    }\r\n   ]\r\n<\/pre>\n<p>8. Next let us define a constant mock and assign it to the response that we want to return.<\/p>\n<pre lang=\"javascript\">\r\nconst mocks = {\r\n  Employees: () => ({\r\n    edges: employees.map(employee => ({ node: employee }))\r\n  }),\r\n};\r\n<\/pre>\n<p>Here, mock object contains the property, <code>Employees<\/code>. The value of this property is a function that returns an object that represents the mock data for the <code>Employees<\/code> type that we defined in our query. This object contains an <code>edges<\/code> property which is an array of objects, where each object represents a node which contains the employee data.<\/p>\n<p>9. Finally, lets pass this mock object as an argument to the <code>addMocksToSchema<\/code> function<\/p>\n<pre lang=\"javascript\">\r\nconst server = new ApolloServer({\r\n    schema: addMocksToSchema({\r\n      schema: makeExecutableSchema({ typeDefs, resolvers }),\r\n      mocks,\r\n      preserveResolvers: true,\r\n    }),\r\n  });\r\n<\/pre>\n<p>10. Our final code should look like this:<\/p>\n<pre lang=\"javascript\">\r\nconst { ApolloServer } = require('@apollo\/server');\r\nconst { startStandaloneServer } = require('@apollo\/server\/standalone');\r\nconst { addMocksToSchema } = require ('@graphql-tools\/mock');\r\nconst { makeExecutableSchema } =  require('@graphql-tools\/schema');\r\n\r\nconst typeDefs = `#graphql\r\n  type Query {\r\n    resolved: String\r\n    allEmployees: Employees\r\n  }\r\n  \r\n  type Employees {\r\n    edges: [EmployeeEdge]\r\n  }\r\n\r\n  type EmployeeEdge {\r\n    node: Employee\r\n  }\r\n\r\n  type Employee {\r\n    email: String\r\n    employeeId: String\r\n    dateJoined: String\r\n    isActive: String\r\n    blogAuthorName: String\r\n    firstname: String\r\n    lastname: String\r\n  }\r\n`;\r\n\r\nconst resolvers = {\r\n    Query: {},\r\n  };\r\n\r\n  let employees = [ \r\n    {\r\n        \"email\": \"smart_learner@qxf2.com\",\r\n        \"employeeId\": \"4\",\r\n        \"dateJoined\": \"04-Sept-1976\",\r\n        \"isActive\": \"Y\",\r\n        \"blogAuthorName\": \"user4\",\r\n        \"firstname\": \"Smart\",\r\n        \"lastname\": \"Learner\"\r\n    },\r\n\r\n    {\r\n        \"email\": \"slow_learner@qxf2.com\",\r\n        \"employeeId\": \"5\",\r\n        \"dateJoined\": \"25-Feb-1977\",\r\n        \"isActive\": \"Y\",\r\n        \"blogAuthorName\": \"user3\",\r\n        \"firstname\": \"Slow\",\r\n        \"lastname\": \"Learner\"\r\n    }\r\n   ]\r\n\r\nconst mocks = {\r\nEmployees: () => ({\r\n  edges: employees.map(employee => ({ node: employee }))\r\n  }),\r\n};\r\n\r\nconst server = new ApolloServer({\r\n    schema: addMocksToSchema({\r\n      schema: makeExecutableSchema({ typeDefs, resolvers }),\r\n      mocks,\r\n      preserveResolvers: true,\r\n    }),\r\n  });\r\n\r\nconst server_port = 5000\r\nconst { url } = startStandaloneServer(server, {listen: { port: server_port }});\r\n  \r\nconsole.log(`\ud83d\ude80 Server listening at Port: ${server_port}`);\r\n<\/pre>\n<p>11. Now run the script again and go to http:\/\/localhost:5000\/. Run the query again<\/p>\n<pre lang=\"graphql\">\r\nquery findAllEmployees {\r\n  allEmployees {\r\n    edges {\r\n      node {\r\n        email\r\n        employeeId\r\n        dateJoined\r\n        isActive\r\n        blogAuthorName\r\n        firstname\r\n        lastname\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>12. You should see following response:<\/p>\n<pre lang=\"graphql\">\r\n{\r\n  \"data\": {\r\n    \"allEmployees\": {\r\n      \"edges\": [\r\n        {\r\n          \"node\": {\r\n            \"email\": \"smart_learner@qxf2.com\",\r\n            \"employeeId\": \"4\",\r\n            \"dateJoined\": \"04-Sept-1976\",\r\n            \"isActive\": \"Y\",\r\n            \"blogAuthorName\": \"user4\",\r\n            \"firstname\": \"Smart\",\r\n            \"lastname\": \"Learner\"\r\n          }\r\n        },\r\n        {\r\n          \"node\": {\r\n            \"email\": \"slow_learner@qxf2.com\",\r\n            \"employeeId\": \"5\",\r\n            \"dateJoined\": \"25-Feb-1977\",\r\n            \"isActive\": \"Y\",\r\n            \"blogAuthorName\": \"user3\",\r\n            \"firstname\": \"Slow\",\r\n            \"lastname\": \"Learner\"\r\n          }\r\n        }\r\n      ]\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>Voila!! And that is how we mock the responses for a query.<\/p>\n<h4>F. Mocking the Authentication<\/h4>\n<p>We explored the process of virtualizing GraphQL responses. Now, moving on, let&#8217;s delve into how we can mock the authentication process. The virtualization of GraphQL authentication process can be divided into two distinct parts:<\/p>\n<p>1. Mocking the generation of tokens.<br \/>\n2. Validation of tokens in the header.<\/p>\n<p>It&#8217;s important to note that the microservice we&#8217;re virtualizing utilizes JWT for authentication. Therefore, this example is written with that specific implementation in mind. However, if your microservice uses a different form of authentication, you can adapt these steps accordingly.<\/p>\n<h5> F1. Mocking the generation of tokens <\/h5>\n<p>1. To mock the generation of tokens, we need to mock the <code>mutation<\/code> which is used to return the access tokens<\/p>\n<pre lang=\"graphql\">\r\nmutation {\r\n    auth(password: \"A_PASSWORD_YOU_SET\", username: \"A_USERNAME_YOU_SELECT\") {\r\n        accessToken\r\n        refreshToken\r\n        }\r\n}\r\n<\/pre>\n<p>2. To mock this <code>mutation<\/code>, lets first define a new type <code>Mutation<\/code> under <code>typeDef<\/code>.<\/p>\n<pre lang=\"javascript\">\r\n type Mutation {\r\n    auth(username: String, password: String): Auth\r\n  }\r\n<\/pre>\n<p>As, we saw in the previous section <code>Mutation<\/code> consists of a field <code>auth<\/code> which is of a custom type <code>Auth<\/code>.<br \/>\n3. So, lets define the type <code>Auth<\/code> as well.<\/p>\n<pre lang=\"javascript\">\r\n  type Auth {\r\n    accessToken: String\r\n    refreshToken: String\r\n  }\r\n<\/pre>\n<p>Here, Auth contains two fields <code>accessToken<\/code> and <code>refreshToken<\/code> both of type <strong>String<\/strong><br \/>\n4. Lets create an environment file that would store our mock credentials in the same directory as our node project. Add the variables USERNAME, PASSWORD, ACCESS_TOKEN, REFRESH_TOKEN and assign some dummy values to it. <\/p>\n<pre lang=\"env\">\r\n#.env\r\nGRAPHQl_USERNAME=\"dummy\"\r\nGRAPHQL_PASSWORD=\"dummy\"\r\nACCESS_TOKEN=\"dummy-token\"\r\nREFRESH_TOKEN=\"dummy-token\"\r\n<\/pre>\n<p>5. We can then use the <code>dotenv<\/code> library to import the environment variable to our Javascript file. Lets first import the <code>dotenv<\/code> library<\/p>\n<pre lang=\"javascript\">\r\nrequire('dotenv').config();\r\n<\/pre>\n<p>6. Next, we need to define what happens when the <code>Mutation<\/code> is invoked. Lets handle this with our <code>resolvers<\/code>.<\/p>\n<pre lang=\"javascript\">\r\nconst resolvers = {\r\n  Query: {},\r\n  Mutation: {\r\n    auth: (_, { username, password }) => {\r\n      if (username === process.env.USERNAME && password === process.env.PASSWORD) {\r\n        return {\r\n          accessToken: process.env.ACCESS_TOKEN,\r\n          refreshToken: process.env.REFRESH_TOKEN\r\n        };\r\n      } else {\r\n        return {\r\n          accessToken: null,\r\n          refreshToken: null\r\n        };\r\n      }\r\n    },\r\n  },\r\n};\r\n<\/pre>\n<p>Here the <code>Mutation<\/code> takes two input parameters, <code>username<\/code> and <code>password<\/code>, The <code>username<\/code> and <code>password<\/code> are compared with the <strong>USERNAME<\/strong> and <strong>PASSWORD<\/strong> that we specified in our environment file. If both the strings match then the values of <code>accessToken<\/code> and <code>refreshToken<\/code> defined in our environment file are returned, If the strings do not match then null values are returned.<\/p>\n<p>Now that we have mocked the generation of tokens, lets take a look at how we can validate these tokens.<\/p>\n<h5>F2. Validation of tokens in the header<\/h5>\n<p>In the real service that we are trying to mock, the access token generated needs to be passed in the <code>Authorization<\/code> header for authorization of query requests. It returns an error message &#8220;<em>object of type &#8216;AuthInfoField&#8217; has no len()<\/em>&#8221; incase the <code>Authorization<\/code> Header is not present or is incorrect.<\/p>\n<p><strong>Note:<\/strong> It is to be noted that the current implementation of the service that is mocked has an issue with its error handling. In the case that the Authorization header is absent or invalid, we should be receiving a 401 Unauthorized response code, however, the implementation returns a 200 response code.<\/p>\n<p>1. To mock this process let&#8217;s first fetch the authorization header from the request. We can do this by passing <code>req.headers.authorization<\/code> that fetches the <strong>Authorization<\/strong> header, in the <code>startStandaloneServer<\/code> method.<\/p>\n<pre lang=\"javascript\">\r\nconst { url } = startStandaloneServer(server, {\r\n    context: async ({ req, res }) => {\r\n      const token = req.headers.authorization || '';\r\n      return { token };\r\n    },\r\n    listen: { port: server_port },\r\n  });\r\n<\/pre>\n<p>Here, we get the header value and assign it to a constant <code>token<\/code><\/p>\n<p>2. Now that we have fetched the authorization header, we need to call it inside our <code>resolvers<\/code>. Since we are trying to add authorization to the Query <code>allEmployees<\/code>, lets first define <code>allEmployees<\/code> in our Query resolver. <\/p>\n<pre lang=\"javascript\">\r\n    Query: {\r\n      allEmployees: () => {},\r\n    }\r\n<\/pre>\n<p>3. Now since we have to raise a <code>GraphQL<\/code> error in case the Authorization Header is incorrect or not present, let&#8217;s import the error module that will help us raise this error from the <code>graphql<\/code> package.<\/p>\n<pre lang=\"javascript\">\r\nconst { GraphQLError } = require('graphql');\r\n<\/pre>\n<p>4. Next, we can call the <code>context<\/code> method which contains the <code>token<\/code> object in our <code>allEmployees<\/code> query resolver. We can then compare the token to check if it matches with the expected token, and raise an error which mimics the error we would receive in the actual service if the tokens do not match.<\/p>\n<pre lang=\"javascript\">\r\n    Query: {\r\n      allEmployees: (root, args, context) => {\r\n        if (context.token != `Bearer ${process.env.ACCESS_TOKEN}`) {\r\n          throw new GraphQLError(\"object of type 'AuthInfoField' has no len()\", {\r\n            extensions: {\r\n              code: 'Unauthorized'\r\n            },\r\n          });\r\n      }\r\n      },\r\n    }\r\n<\/pre>\n<p>5. Finally, lets disable the <a href=\"https:\/\/www.apollographql.com\/docs\/apollo-server\/data\/errors\/#omitting-or-including-stacktrace\" rel=\"noopener\" target=\"_blank\">stacktrace<\/a> for the error as we are just mocking the error received in the actual service. To do this we need to pass the <code>includeStacktraceInErrorResponses<\/code> option to the constructor of <code>ApolloServer<\/code> and set it to false<\/p>\n<pre lang=\"javascript\">\r\nconst server = new ApolloServer({\r\n    schema: addMocksToSchema({\r\n      schema: makeExecutableSchema({ typeDefs, resolvers }),\r\n      mocks,\r\n      preserveResolvers: true,\r\n    }),\r\n    includeStacktraceInErrorResponses: false\r\n  });\r\n<\/pre>\n<h4>G. Putting it all together<\/h4>\n<p>That&#8217;s it! We are finally done with our coding. Our complete code should look similar to this:<\/p>\n<pre lang=\"javascript\">\r\nconst { ApolloServer } = require('@apollo\/server');\r\nconst { startStandaloneServer } = require('@apollo\/server\/standalone');\r\nconst { addMocksToSchema } = require ('@graphql-tools\/mock');\r\nconst { makeExecutableSchema } =  require('@graphql-tools\/schema');\r\nconst { GraphQLError } = require('graphql');\r\nconst fs = require('fs');\r\nrequire('dotenv').config();\r\n\r\nconst typeDefs = `#graphql\r\n  type Query {\r\n    allEmployees: Employees\r\n  }\r\n  \r\n  type Mutation {\r\n    auth(username: String, password: String): Auth\r\n  }\r\n\r\n  type Auth {\r\n    accessToken: String\r\n    refreshToken: String\r\n  }\r\n\r\n  type Employees {\r\n    edges: [EmployeeEdge]\r\n  }\r\n\r\n  type EmployeeEdge {\r\n    node: Employee\r\n  }\r\n\r\n  type Employee {\r\n    email: String\r\n    employeeId: String\r\n    dateJoined: String\r\n    isActive: String\r\n    blogAuthorName: String\r\n    firstname: String\r\n    lastname: String\r\n  }\r\n`;\r\n\r\nconst resolvers = {\r\n    Query: {\r\n      allEmployees: (root, args, context) => {\r\n        if (context.token != `Bearer ${process.env.ACCESS_TOKEN}`) {\r\n          throw new GraphQLError(\"object of type 'AuthInfoField' has no len()\", {\r\n            extensions: {\r\n              code: 'Unauthorized'\r\n            },\r\n          });\r\n      }\r\n      },\r\n    },\r\n    Mutation: {\r\n      auth: (_, { username, password }) => {\r\n        if (username === process.env.USERNAME && password === process.env.PASSWORD) {\r\n          return {\r\n            accessToken: process.env.ACCESS_TOKEN,\r\n            refreshToken: process.env.REFRESH_TOKEN\r\n          };\r\n        } else {\r\n          return {\r\n            accessToken: null,\r\n            refreshToken: null\r\n          };\r\n        }\r\n      },\r\n    },\r\n  };\r\n\r\n  let employees = [ \r\n    {\r\n        \"email\": \"smart_learner@qxf2.com\",\r\n        \"employeeId\": \"4\",\r\n        \"dateJoined\": \"04-Sept-1976\",\r\n        \"isActive\": \"Y\",\r\n        \"blogAuthorName\": \"user4\",\r\n        \"firstname\": \"Smart\",\r\n        \"lastname\": \"Learner\"\r\n    },\r\n\r\n    {\r\n        \"email\": \"slow_learner@qxf2.com\",\r\n        \"employeeId\": \"5\",\r\n        \"dateJoined\": \"25-Feb-1977\",\r\n        \"isActive\": \"Y\",\r\n        \"blogAuthorName\": \"user3\",\r\n        \"firstname\": \"Slow\",\r\n        \"lastname\": \"Learner\"\r\n    }\r\n   ]\r\n\r\nconst mocks = {\r\nEmployees: () => ({\r\n  edges: employees.map(employee => ({ node: employee }))\r\n }),\r\n};\r\n  \r\nconst server = new ApolloServer({\r\n    schema: addMocksToSchema({\r\n      schema: makeExecutableSchema({ typeDefs, resolvers }),\r\n      mocks,\r\n      preserveResolvers: true,\r\n    }),\r\n    includeStacktraceInErrorResponses: false\r\n  });\r\n  \r\nconst server_port = 5000\r\nconst { url } = startStandaloneServer(server, {\r\n    context: async ({ req, res }) => {\r\n      const token = req.headers.authorization || '';\r\n      return { token };\r\n    },\r\n    listen: { port: server_port },\r\n  });\r\n    \r\nconsole.log(`\ud83d\ude80 Server listening at Port: ${server_port}`);\r\n<\/pre>\n<p>1. Start your server, navigate to http:\/\/localhost:5000\/. Try running the query <code>findAllEmployees<\/code> again:<\/p>\n<pre lang=\"graphql\">\r\nquery findAllEmployees {\r\n  allEmployees {\r\n    edges {\r\n      node {\r\n        email\r\n        employeeId\r\n        dateJoined\r\n        isActive\r\n        blogAuthorName\r\n        firstname\r\n        lastname\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>You would see an <strong>Unauthorized<\/strong> error in your response.<\/p>\n<p>2. You can add a header by clicking on the <code>headers<\/code> tab in the Apollo server&#8217;s web interface itself.<\/p>\n<figure id=\"attachment_17623\" aria-describedby=\"caption-attachment-17623\" style=\"width: 900px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/header_modified.png\" data-rel=\"lightbox-image-1\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/header_modified-1024x466.png\" alt=\"Apollo server&#039;s Header Tab\" width=\"900\" height=\"410\" class=\"size-large wp-image-17623\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/header_modified-1024x466.png 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/header_modified-300x137.png 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/header_modified-768x350.png 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/header_modified-1536x699.png 1536w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/header_modified.png 1848w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption id=\"caption-attachment-17623\" class=\"wp-caption-text\">Set the Header for your query request with Apollo Server&#8217;s inbuilt Header feature<\/figcaption><\/figure>\n<p>3. Set the header key to <code>Authorization<\/code> and value to <code>'Bearer <ACCESSS_TOKEN set in environment file>'<\/code>. In our case the header would be <code><strong>Authorization<\/strong>: <strong>Bearer dummy-token<\/strong><\/code><\/p>\n<figure id=\"attachment_17563\" aria-describedby=\"caption-attachment-17563\" style=\"width: 900px\" class=\"wp-caption alignnone\"><a href=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/set_header-1.jpg\" data-rel=\"lightbox-image-2\" data-rl_title=\"\" data-rl_caption=\"\" title=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/set_header-1-1024x496.jpg\" alt=\"Setting headers through Apollo server web interface\" width=\"900\" height=\"436\" class=\"size-large wp-image-17563\" srcset=\"https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/set_header-1-1024x496.jpg 1024w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/set_header-1-300x145.jpg 300w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/set_header-1-768x372.jpg 768w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/set_header-1-1536x745.jpg 1536w, https:\/\/qxf2.com\/blog\/wp-content\/uploads\/2023\/02\/set_header-1.jpg 1912w\" sizes=\"auto, (max-width: 900px) 100vw, 900px\" \/><\/a><figcaption id=\"caption-attachment-17563\" class=\"wp-caption-text\">Setting Headers for the GraphQL query request<\/figcaption><\/figure>\n<p>4. Now run the query again, you would see that the actual response is returned this time.<\/p>\n<hr>\n<h4>Hire Qxf2!<\/h4>\n<p><a href=\"https:\/\/qxf2.com\/?utm_source=ApolloServer&#038;utm_medium=click&#038;utm_campaign=From%20blog\">Qxf2<\/a> is the home of technical testers. We help in testing early stage products and love working with small engineering teams. We employ many emerging testing techniques and implement test ideas using a whole suite of modern testing tools. If this post helped you, consider hiring a tester from Qxf2 for your project. You can get in touch with us via <a href=\"https:\/\/qxf2.com\/contact?utm_source=ApolloServer&#038;utm_medium=click&#038;utm_campaign=From%20blog\">this contact form<\/a>.<\/p>\n<hr>\n","protected":false},"excerpt":{"rendered":"<p>There is plenty of information online about how to virtualize REST based microservices. At our clients, Qxf2 has implemented different techniques like using a Flask app, using wiremock, etc. But recently we found the need to for virtualizing a GraphQL microservice to expand the scope of our test automation on our CI environment. In this post, we will show one [&hellip;]<\/p>\n","protected":false},"author":29,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[324,287,256,64,325],"tags":[],"class_list":["post-17491","post","type-post","status-publish","format-standard","hentry","category-apollo-server","category-graphql","category-microservices","category-mock","category-mock-graphql"],"_links":{"self":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/17491","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/users\/29"}],"replies":[{"embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/comments?post=17491"}],"version-history":[{"count":81,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/17491\/revisions"}],"predecessor-version":[{"id":17675,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/posts\/17491\/revisions\/17675"}],"wp:attachment":[{"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/media?parent=17491"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/categories?post=17491"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/qxf2.com\/blog\/wp-json\/wp\/v2\/tags?post=17491"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}