> This page is for Developer.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.bigcommerce.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.bigcommerce.com/_mcp/server.

# Lab - Create a Search and Filter Flow in Postman

Plan: Developer Foundations

Lesson 20 of 28 · 45 min

## Introduction

In this lab, you'll utilize the environment configuration you've already created in Postman to create a series of request that will progressively filter a product search query.

Certain catalog data must be present in your BigCommerce store in order for the exercise queries to succeed. We'll detail the requirements below.

### In this lab, you will:

* Create a series of queries to filter product results

### Prerequisites

* A BigCommerce [sandbox store](/developer/docs/overview/sandboxes) or [trial store](https://www.bigcommerce.com/essentials/), or a full production store
* [Postman](https://www.postman.com/)
* Products and categories with configuration according to the guidelines below

### Catalog Data Prerequisites

In the requests you'll be creating, you'll be starting out querying for products on a specific search term, then capturing and applying other available filters to continue narrowing the results set. We'll be filtering on these facets:

* A top-level category
* A variant option value

In order to support this flow, you'll need a pool of at least four products following these guidelines:

* All products must include the same search term in their name.
* Various products should be assigned to the same top-level categories.
* All products must include a variant option with the same name.
* Various values for the variant option should be shared among different products, but not all products.

The common category assignments and values between products should allow for varied results sets depending on what filters are applied. Below is an example product set.

| Product Name         | Categories                              | Variant Option            |
| -------------------- | --------------------------------------- | ------------------------- |
| Athletic T-Shirt     | Fitness, Casual Wear, Professional Wear | Color: Black, Grey, Red   |
| Casual T-Shirt       | Casual Wear, On Sale                    | Color: White, Red         |
| Professional T-Shirt | Fitness, Professional Wear, On Sale     | Color: Black, White, Blue |
| Striped T-Shirt      | Casual Wear, Professional Wear, On Sale | Color: Grey, Blue, Black  |

In your Product Filters settings in the BigCommerce control panel, make sure the **Category** and **Variant** options are enabled as visible filters at the global or channel level.

## Postman Recap

This lab will not require any of the collection variables captured by requests in the previous exercise, but it's necessary that the following still be in place:

1. An environment with variables set for `v3_token`, `store_hash`, `storefront_channel_id` and `private_storefront_token`.
2. A collection with Bearer Token authentication using the value of `private_storefront_token` (Postman sends server-to-server requests, so the Private Token is used; the Storefront token is for browser use only).
3. A "REST Create Private Token (server-to-server)" request that will populate `private_storefront_token` when run.

## Create a Search Request

### Step 1: Create the Request

1. In the Variables tab of your collection, **create** a variable named `filter_search_term` with the search term that will capture your chosen products as the value.
2. **Create** a new "GQL Product Search" HTTP request and **save** it to your collection. This request requires the following details.

| Field                         | Value                                                                              |
| ----------------------------- | ---------------------------------------------------------------------------------- |
| Method                        | POST                                                                               |
| URL                           | `https://store-{{store_hash}}-{{storefront_channel_id}}.mybigcommerce.com/graphql` |
| Authorization                 | Inherit auth from parent                                                           |
| Settings > Disable cookie jar | On                                                                                 |
| Body type                     | GraphQL                                                                            |

3. In the Headers tab, **select** your GraphQL headers preset to apply "Accept" and "Content-Type" headers.
4. **Enter** the following query in the Body tab:

```graphql showLineNumbers={false}
query Search(
    $searchTerm: String
) {
    site {
        search {
            searchProducts(
                filters: {
                    searchTerm: $searchTerm
                }
            ) {
                filters {
                    edges {
                        node {
                            name
                            __typename
                            ... on ProductAttributeSearchFilter {
                                filterName
                                attributes {
                                    edges {
                                        node {
                                            value
                                            isSelected
                                        }
                                    }
                                }
                            }
                            ... on CategorySearchFilter {
                                categories {
                                    edges {
                                        node {
                                            entityId
                                            name
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                products {
                    collectionInfo {
                        totalItems
                    }
                    edges {
                        node {
                            sku
                            name
                            categories {
                                edges {
                                    node {
                                        entityId
                                        name
                                    }
                                }
                            }
                            productOptions {
                                edges {
                                    node {
                                        displayName
                                        ... on MultipleChoiceOption {
                                            values {
                                                edges {
                                                    node {
                                                        entityId
                                                        label
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```

5. **Enter** the following in the GraphQL Variables section of the Body tab:

```json showLineNumbers={false}
{
    "searchTerm": "{{filter_search_term}}"
}
```

6. **Send** the request and observe the response.

The search response should include the products that match your search term, and the fields included should make it easy to predict which products will continue to be included in the set as you continue to narrow it with filters.

The `data.site.search.searchProducts.filters` data should also enumerate the available filter values that can be applied to the product results.

### Step 2: Add Tests

1. **Enter** the following "Post-response" value in the Scripts tab:

```js showLineNumbers={false}
pm.test("Response is not an error", () => {
    pm.response.to.not.be.error;
    pm.response.to.not.have.jsonBody("errors");
});
pm.test("Response is JSON with data", () => {
    pm.response.to.have.jsonBody("data");
});

const products = pm.response.json().data?.site?.search?.searchProducts?.products?.edges
    ?? [];
pm.test("Response includes at least one product", () => {
    pm.expect(products.length).to.be.above(0);
});

const filterValueIndex = 0;

const availableFilters = pm.response.json().data?.site?.search?.searchProducts?.filters?.edges
    ?? [];
const availableCatFilter = availableFilters.find(filter => {
    return filter.node?.__typename === "CategorySearchFilter";
});
pm.test("Response includes available category filters", () => {
    pm.expect(availableCatFilter?.node?.categories?.edges?.length)
        .to.be.above(filterValueIndex);
});
```

2. **Send** the request again and **verify** that all tests are successful.

### Step 3: Store a Category Filter

The tests you've put in place confirm that at least one available category filter is present in the response. Let's add code to capture the *first* available filter value in a collection variable to use in the next request.

1. **Add** the following after the previous code in Scripts:

```java showLineNumbers={false}
pm.collectionVariables.unset("filter_category");
const newCatFilter = availableCatFilter?.node?.categories?.edges[filterValueIndex]?.node;
pm.collectionVariables.set("filter_category", newCatFilter?.entityId);
```

2. **Send** the request again and **verify** that the `filter_category` variable is populated in your collection with the ID of a category.

> **Info**
>
> If you want a different category value than the first to be used to further filter the results, update the `filterValueIndex` value in the Tests code. (The value is zero-based, so it should be off-set by one compared to the position of the desired value in the filter list.)

## Narrow Search Results by Category

You'll now create a request that is identical to the previous one, but *adding* a filter on the category ID to the query. The easiest way to do this in Postman is to *duplicate* the request initially.

### Step 1: Create the Request

1. **Duplicate** the request "GQL Product Search" in the collection and **rename** the new request "GQL Product Search - Cat."
2. **Clear** the contents of the Tests tab.
3. In the Body, **update** the variables and filter arguments in the query as follows:

```graphql showLineNumbers={false}
query Search(
    $searchTerm: String,
    $categoryId: Int!
) {
    site {
        search {
            searchProducts(
                filters: {
                    searchTerm: $searchTerm,
                    categoryEntityId: $categoryId
                }
            ) {
              ... // LEAVE QUERIED FIELDS UNCHANGED //
            }
        }
    }
}
```

4. **Update** the GraphQL Variables section of the Body tab:

```json showLineNumbers={false}
{
    "searchTerm": "{{filter_search_term}}",
    "categoryId": {{filter_category}}
}
```

5. **Send** the request and observe the results.

You should observe a smaller product results set than in the previous request.

### Step 2: Add Tests

1. **Enter** the following "Post-response" value in the Scripts tab:

```js showLineNumbers={false}
pm.test("Response is not an error", () => {
    pm.response.to.not.be.error;
    pm.response.to.not.have.jsonBody("errors");
});
pm.test("Response is JSON with data", () => {
    pm.response.to.have.jsonBody("data");
});

const products = pm.response.json().data?.site?.search?.searchProducts?.products?.edges
    ?? [];
pm.test("Response includes at least one product", () => {
    pm.expect(products.length).to.be.above(0);
});

const filterValueIndex = 0;
const variantFilterName = "Color";

const availableFilters = pm.response.json().data?.site?.search?.searchProducts?.filters?.edges
    ?? [];
const availableVariantFilter = availableFilters.find(filter => {
    return filter.node.name === variantFilterName;
});
pm.test("Response includes available variant filters", () => {
    pm.expect(availableVariantFilter?.node?.attributes?.edges?.length)
        .to.be.above(filterValueIndex);
});
```

Replace the value of `variantFilterName` ("Color" in the above code) with the exact name of the variant option you want to filter on.

2. **Send** the request again and **verify** that tests are successful.

### Step 3: Store a Variant Filter

Just as with category, you'll find and store the first available value for your chosen variant option.

1. **Add** the following after the previous code in Scripts:

```java showLineNumbers={false}
pm.collectionVariables.unset("filter_variant_attr_name");
pm.collectionVariables.unset("filter_variant_attr_val");
const newVariantFilter = availableVariantFilter?.node?.attributes?.edges[0]?.node;
pm.collectionVariables.set("filter_variant_attr_name", variantFilterName);
pm.collectionVariables.set("filter_variant_attr_val", newVariantFilter?.value);
```

2. **Send** the request again and **verify** that values for `filter_variant_attr_name` and `filter_variant_attr_val` are populated on the collection.

![Image](/_fern-files/bigcommerce.docs.buildwithfern.com/65d5c22a2d4f9cac53ddf536d2982906123da8b0fcd9485f2a31d5eb58638cad/assets/learn/graphql-storefront-api/postman-variant-vars.png)

## Narrow Search Results By Variant Value

### Step 1: Create the Request

1. **Duplicate** the request "GQL Product Search - Cat" in the collection and **rename** the new request "GQL Product Search - Cat, Variant".
2. **Clear** the contents of the Tests tab.
3. In the Body, **update** the variables and filter arguments in the query as follows:

```graphql showLineNumbers={false}
query Search(
    $searchTerm: String,
    $categoryId: Int!,
    $variantAttrName: String!,
    $variantAttrVal: String!
) {
    site {
        search {
            searchProducts(
                filters: {
                    searchTerm: $searchTerm,
                    categoryEntityId: $categoryId,
                    productAttributes: [
                        {
                            attribute: $variantAttrName,
                            values: [$variantAttrVal]
                        }
                    ]
                }
            ) {
              ... // LEAVE QUERIED FIELDS UNCHANGED //
            }
        }
    }
}
```

4. **Update** the GraphQL Variables section of the Body tab:

```json showLineNumbers={false}
{
    "searchTerm": "{{filter_search_term}}",
    "categoryId": {{filter_category}},
    "variantAttrName": "{{filter_variant_attr_name}}",
    "variantAttrVal": "{{filter_variant_attr_val}}"
}
```

5. **Send** the request and observe the results.

This time, in addition to your (hopefully) narrowed results set, you should also be able to observe that the `isSelected` field is true for the variant filter that was captured and applied.

### Step 2: Add Tests

1. **Enter** the following "Post-response" value in the Scripts tab:

```js showLineNumbers={false}
pm.test("Response is not an error", () => {
    pm.response.to.not.be.error;
    pm.response.to.not.have.jsonBody("errors");
});
pm.test("Response is JSON with data", () => {
    pm.response.to.have.jsonBody("data");
});

const products = pm.response.json().data?.site?.search?.searchProducts?.products?.edges
    ?? [];
pm.test("Response includes at least one product", () => {
    pm.expect(products.length).to.be.above(0);
});
```

2. **Send** the request again and **verify** that all tests are successful.