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:

valentine homepage

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 &rarr;</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!!

valentine homepage

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!