As businesses evolve in the digital age, the demand for efficient and streamlined data integration grows exponentially. One of the best ways to accomplish this is using a GraphQL API, which allows developers to access multiple data sources through a single endpoint easily. StepZen is a powerful tool that helps you create a GraphQL API for every data source using a declarative approach. And to further enhance the capabilities of StepZen, you can use jq to transform REST API JSON responses in a declarative way.

In this step-by-step guide, you'll learn how to use StepZen to transform a REST API into a GraphQL API and apply powerful transformations to the JSON data using jq.

Do you prefer watching a video walkthrough instead? Check out the link below:

Watch a video walkthrough of Transforming REST APIs with "jq" in GraphQL

What is jq?

jq is an open-source command-line JSON processing tool that is particularly useful for working with machine-readable data formats and can be especially helpful in shell scripts. It can assist in data manipulation by extracting specific information from JSON API server responses, making it an excellent choice for data engineers looking to streamline their data ingestion processes.

When creating a StepZen GraphQL API, you can use jq to transform the JSON data returned by a REST API. Not from the command line but in a GraphQL schema, which allows you to create a GraphQL API that returns data in a more suitable format for your application. In this blog post, we'll use jq to transform the JSON data returned by a dummy REST API.

Creating a new StepZen GraphQL API

First, you'll need to install the StepZen CLI by running the following command:

npm i -g stepzen

Once you've installed the CLI, you can import the dummy REST API into a new StepZen GraphQL schema. Before doing so, you'll need to create a new working directory. You can do this by running the following commands:

mkdir stepzen-jq
cd stepzen-jq

From this new directory, we'll import the free dummy REST API https://dummyjson.com/products by running the following command:

stepzen import curl http://dummyjson.com/products --name=dummyapi --query-name=products

Also have a look at the Getting Started example for REST APIs, which explains how to create a StepZen GraphQL API from a REST API in more detail.

This will generate a new schema that describes the API's data structure in GraphQL. In this case, the generated schema will look like this:

type ProductsEntry {
  brand: String
  category: String
  description: String
  discountPercentage: Float
  id: Int
  images: [String]
  price: Int
  rating: Float
  stock: Int
  thumbnail: String
  title: String
}

type Root {
  limit: Int
  products: [ProductsEntry]
  skip: Int
  total: Int
}

type Query {
  products: Root @rest(endpoint: "https://dummyjson.com/products")
}

You can now use the stepzen start command to start the GraphQL API server. From the StepZen dashboard, you can explore the GraphQL API and see the data that is returned by the API.

The following query will return a list of products:

{
  products {
    products {
      id
      title
      price
      category
    }
  }
}

As you can see in the above query, the products data is returned in a nested format. This is because of the REST API response. We'll use jq to transform the JSON response to make the data easier to work with. Next, we'll add a jq transformation to the products query to manipulate the REST API's JSON response.

Transforming REST APIs with jq

To transform the response of a REST API in StepZen, we'll modify the schema to include the transforms option in the @rest directive. Specifically, we'll add the jq transformation to the editor field in the transforms option.

Here's what the modified schema will look like when we add a jq transformation to only return the products field from the REST API response:

type ProductsEntry {
  brand: String
  category: String
  description: String
  discountPercentage: Float
  id: Int
  images: [String]
  price: Int
  rating: Float
  stock: Int
  thumbnail: String
  title: String
}

type Query {
  products: [ProductsEntry] @rest(
    endpoint: "https://dummyjson.com/products",
    transforms: [
      {
        pathpattern: [],
        editor:"""
          jq: .products[]
        """
      }
    ]
  )
}

Note that we've removed the Root type from the schema and added the transforms option to the @rest directive for the products query. The transforms option takes a list of objects that specify how the REST API's JSON response should be transformed. In this case, we're using the jq editor to transform the JSON response by applying the .products[] formula to it.

You can send a GraphQL query to the StepZen API endpoint to test the modified schema. For example:

{
  products {
    id
    title
    price
    category
  }
}

This query will return a list of ProductsEntry objects transformed using the jq formula. The StepZen GraphQL API will return the transformed data instead of the original REST API response, so you no longer need your schema's Root type. In the next section, let's try a more complex transformation using jq.

Filtering REST API responses with jq

We've already used a basic jq formula to transform the JSON response from the REST API. In this section, we'll use a more complex jq formula to filter the products returned by the REST API.

To filter the products, we'll use the jq formula:

.products | map(select(.category | contains(get("category")))) | .[]

This formula will filter the products array and return only the products that match the specified category. The get("category") part will get the value of the category argument passed to the GraphQL query.

Here's how we can add the filter to the products query in the GraphQL schema:

type Query {
  products(category: String!): [ProductsEntry]
    @rest(
      endpoint: "https://dummyjson.com/products"
      transforms: [
        {
          pathpattern: [],
          editor:"""
            jq:.products | map(select(.category | contains(get("category")))) | .[]
          """
        }
      ]
    )
}

Now we can query the GraphQL API and filter the products by category. For example, to get all the products in the "smartphones" category, we can use the following GraphQL query:

{
  products(category: "smartphones") {
    id
    title
    price
    category
  }
}

That's how you can use jq to transform a REST API JSON response in a StepZen GraphQL API and also add a filter to the query. Using jq to transform REST API responses is a developer-friendly way of customizing the output of your GraphQL queries, but comes with a few limitations such as degraded performance as the execution time increases. Keep this in mind when using jq to transform REST API responses in your StepZen GraphQL API.

Conclusion

In conclusion, using jq to transform REST API responses in a StepZen GraphQL API is a powerful way to integrate data sources efficiently. By taking advantage of the transforms option within the @rest directive, you can easily manipulate JSON data to fit your specific needs. This declarative approach saves time and makes data integration much more efficient and streamlined.

If you have questions about this blog post, you can ask for help on our Discord channel.