How to Use Mocks in Your GraphQL Development Workflow
There are lots of ways you might want to use StepZen for mocking! Particularly if you’re working on a frontend that will query a GraphQL API for data, but the full backend implementation is not ready yet.
Let's imagine you're a web developer working as an independent contractor. As part of a February small-business promotion, your local town wants to hire you to create a Valentine's Day restaurant comparison matrix app. Or any other special occasion for that matter. They'd like to see you create a frontend interface before they commit to using the Yelp API.
This is a perfect case for the @mock
directive! You can use it, and StepZen's directive-first approach, to create an app with a mock backend to show the client.
The Next.js App
The end goal is a simple Next.js app:
As you can see, it shows a list of local restaurants: their names, distances, and prices. This makes it easy to compare them to find the perfect Valentine's Day date location!
The folder structure of the project is fairly typical of a Next app, with the addition of a stepzen folder
:
.
├── \_components
├── \_pages
├── \_stepzen
├── styles
├── ... configuration files ...
└── README.md
The StepZen Folder
Inside the stepzen
folder, we have these files:
├── \_stepzen
│ ├── config.yaml
│ ├── yelp.graphql
│ └── index.graphql
config.yaml
contains any configuration details we might need.
index.graphql
lists the schemas for the StepZen service:
schema @sdl(files: ["yelp.graphql"]) {
query: Query
}
and yelp.graphql
contains the types, enums, and query definitions for the Yelp API. Let's take a look at a type using StepZen's @mock
and @mockfn
directives:
type Yelp_Businesses @mock {
alias: String
url: String
@mockfn(
name: "List"
values: [
"https://www.yelp.com/biz/achilles-santa-clara?adjust_creative=_DJNKa6LbWFyRPRuvkH_BQ&utm_campaign=yelp_api_v3&utm_medium=api_v3_graphql&utm_source=_DJNKa6LbWFyRPRuvkH_BQ", "https://www.yelp.com/biz/tea-time-scottsdale"
]
)
phone: String
review_count: Int
rating: Float
price: String
hours: [Yelp_Hours]
reviews(limit: Int, offset: Int): [Yelp_Review]
distance: Float
}
Here, you can see @mock
is on type Yelp_Businesses
. This means that any query returning the Yelp_Businesses
type will return mock data. It will be general "lorem ipsum", unless you want to achieve a higher level of granularity.
In that case, you can use @mockfn
, which takes two arguments, name
and values
. Here, name
indicates that the type of mock data returned will be a list, and values
is the selected values that will be returned.
Adding these two directives guarantees that this query, yelp_search
, will return mock data, because it returned the Yelp_Businesses
type.
yelp_search(
yelp_apiKey: Secret!g
locale: String
longitude: Float
): Yelp_Businesses
@graphql(
endpoint: "https://api.yelp.com/v3/graphql"
headers: [{ name: "authorization", value: "$yelp_apiKey" }]
configuration: "yelp_config"
)
Let's take a look at the components in the Next.js App to see the data populated to the frontend.
Making the Call to the GraphQL API
In order to make the call, we could use the fetch API and Next's getServerSideProps
function in pages/index.js
, which would keep the call off the client, for security reasons:
import Head from "next/head";
import styles from "../styles/Home.module.css";
export async function getServerSideProps(context) {
let yelp_apiKey = process.env.NEXT_YELP_APIKEY;
const response = await fetch(
"https://user.stepzen.net/api/folder-name/__graphql",
{
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify( query MyQuery($yelp_apiKey: Secret!) {
yelp_search(
yelp_apiKey: $yelp_apiKey
latitude: 38.8951
longitude: -77.0364
) {
business {
distance
review_count
price
alias
}
}
}
`,
variables: {
yelp_apiKey: yelp_apiKey
},
}),
}
);
let data = await response.json();
return { props: data };
}
This makes the call to the StepZen endpoint and returns the data, which, in this case, will be mocked.
The Component
We can then consume the data in a Next component:
export default function HelloValentine({ data }) {
if (error) return JSON.stringify(error)
if (loading) return `Loading ...`
let restaurants = (
<div className={styles.grid}>
<Image
src={photo}
alt="hands holding valentine bouquet"
width="400"
height="400"
/>
<a href="https://graphql.stepzen.com/" className={styles.card}>
<h3>Compare restaurants →</h3>
<ul>
<li>{data.yelp_search.business[0].alias}</li>
<li>{data.yelp_search.business[0].distance}</li>
<li>{data.yelp_search.business[0].price}</li>
</ul>
<br></br>
<ul>
<li>{data.yelp_search.business[1].alias}</li>
<li>{data.yelp_search.business[1].distance}</li>
<li>{data.yelp_search.business[1].price}</li>
</ul>
<br></br>
<ul>
<li>{data.yelp_search.business[2].alias}</li>
<li>{data.yelp_search.business[2].distance}</li>
<li>{data.yelp_search.business[2].price}</li>
</ul>
</a>
</div>
)
return restaurants
}
This will create our Next.js app with mocked data coming from GraphQL!!
This mock data is 'in the shape of' the GraphQL API, so you can confidently create this frontend without worrying about how much it will change once you're hooked up to the API.
If the town approves the design and signs up for a Yelp developer account to give you a key to use, it's a matter of removing the @mock
directive to surface the 'real' data and have a complete, working app.
Where to Go From Here
If you're interested in learning more about our @mock
directive, I suggest checking out our documentation.
You can also try out the Yelp API for yourself in our GraphQL Studio.
If you have questions, feel free to slide into our Discord. We'd love to see you around!