Introduction
Using a mock server for backend APIs streamlines frontend development by eliminating backend dependencies. While it’s relatively simple for RESTful APIs, setting up a GraphQL mock server can be more tedious. This tutorial walks you through creating a GraphQL mock server for your JavaScript application. A mock server is invaluable for local development, allowing seamless testing when the backend is unavailable or during E2E tests.
Prerequisites
Before proceeding, ensure the following tools are installed on your system:
- Node.js
- npm/yarn/pnpm
Step-by-step Guide
1. Install Dependencies
Begin by installing the necessary dependencies with npm or yarn:
npminstall--save-dev graphql graphql-tag graphql-tools @apollo/server node-fetch
2. Setup Project Structure
Set up your project directory as follows:
/graphql-mock-server |-- localSchema.ts |-- schema.graphql |-- server.ts
3. Local Schema
Define your local schema in localSchema.ts. This schema will override remote schema definitions for specific queries or mutations. Provide resolvers to return predefined mock data.
// filepath: /graphql-mock-server/localSchema.tsimport{makeExecutableSchema}from'@graphql-tool/schema'import{gql}from'graphql-tag'consttypeDefs=gql` type Query { myQuery: String }`;constresolvers={Query:{myQuery:()=>'This is mock data'},};exportconstlocalSchema=makeExecutableSchema({typeDefs,resolvers});
4. Remote Schema
The remote schema is loaded from the local fileschema.graphql
. This file should include the schema definition, which can be exported from your GraphQL playground.
// filepath: /graphql-mock-server/schema.graphqltypeQuery{myQuery:String}
5. Mock Server Implementation
The mock server stitches the local and remote schemas, giving precedence to the local schema-specified queries or mutations.
// filepath: /graphql-mock-server/server.tsimport{ApolloServer}from'@apollo/server';import{startStandaloneServer}from'@apollo/server/standalone';import{stitchSchema}from'@graphql-tools/stitch';import{loadSchemaSync}from'@graphql-tools/load';import{GraphQLFileLoader}from'@graphql-tools/graphql-file-loader';import{localSchema}from'./localSchema';import{wrapSchema}from'@graphql-tools/wrap';import{print}from'graphql';importfetchfrom'node-fetch';asyncfunctionstartServer(){constremoteSchema=loadSchemaSync('graphql-mock-server/schema.graphql',{loaders:[newGraphQLFileLoader()],});constexecutableRemoteSchema=wrapSchema({schema:remoteSchema,executor:async({document,variables})=>{constquery=print(document);constfetchResult=awaitfetch('https://graphql.server.com/graphql',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({query,variables}),},);returnfetchResult.json();},});constschema=stitchSchema({subschema:[{schema:executableRemoteSchema},{schema:localSchema},merge:{myQuery:{//override the Query/Mutation hereselectionSet:'{ __typename }',resolve:(parent,args,context,info)=>{returnlocalSchema.getQueryType()?.getFields().myQuery.resolve(parent,args,context,info);},},},},},],});constserver=ApolloServer({schema});const{url}=awaitstartStandaloneServer(server,{listen:{port:4000},});console.log(`🚀 Server ready at${url}`);}startServer();
If you have reached here, then I made a satisfactory effort to keep you reading. Please be kind enough to leave any comments or share corrections.
My Other Blogs:
- @nuxt/test-utils - The First-Class Citizen for Nuxt Unit Testing
- Supercharge Your E2E Tests with Playwright and Cucumber Integration
- Integrate Web Component/MFE with plain static HTML
- Cracking Software Engineering Interviews
- My firsthand experience with web component - learnings and limitations
- Micro-Frontend Decision Framework
- Test SOAP Web Service using Postman Tool
Top comments(0)
For further actions, you may consider blocking this person and/orreporting abuse