[Total: 3   Average: 2.3/5]

GraphQL has grown in popularity since its release in 2015. With the prevalence of JSON and its usage in API development, GraphQL takes it one step further. It does so by creating a standardized query framework that gives you only the data you need — thus increasing your REST API’s flexibility and can significantly reduce the data transfer loads.

It sits on top of what you currently have and supports a range of languages, including but not limited to Haskell, JavaScript, Perl, Python, Ruby, Java, C++, C#, Scala, Go, Rust, Elixir, Erlang, PHP, and Clojure.

The syntax for writing GraphQL is simple to understand and adaptable by various layers of the software development stack.

In this article, we will go over the fundamentals of searching and filtering queries for GraphQL.

Comprehensive guide to GraphQL filtering

Before we can kickstart a query in GraphQL, we need to be able to get a single object. To do this, you need to generate a single list of objects for a type. What this means is that you list out all the things you want returned from that particular object.

Traditionally, an API would just give back a standard format based on what’s been preconfigured in the backend. With GraphQL, you can list out only the fields you require for your needs.

For example:

 query{
    getCart(id: "UUID938204") {
      cartItems
      totalPrice
      VAT
      priceBeforeVat
      numberOfItems
      discountCode
    }
 }

Here’s an example of nested linked objects in GraphQL.

query{
    getCart(id: "UUID938204") {
      cartItems {
        itemSKU
        itemName
        itemPrice
        itemQuantity
        itemDescription
        itemDiscountApplied
      }
      totalPrice
      VAT
      priceBeforeVat
      numberOfItems
      discountCode
    }
 }

There may be other key-pair values available for your query. By limiting the data to only what you need, this is the most basic form of filtering in GraphQL.

You can also add the filter keyword to your query to limit the values returned based on the given parameters. Here is a syntax example of a nested query filter:

 query{
    getCart(id: "UUID938204") {
      cartItems {
        itemDiscountApplied(filter: {
        status: true
        })
      }
      totalPrice
      VAT
      priceBeforeVat
      numberOfItems
      discountCode
    }
 }

It’s also good to note that for this structure you work, your GraphQL scheme needs to have @id in its type. For example:

 type Cart {
    cartUUID: String! @id
    totalPrice: Double
    VAT: Double
    priceBeforeVat: Double
    numberOfItems: Double
    discountCode: String
 }

The @id becomes a filter parameter for your GraphQL query.
To query a list of objects, you can just add an array as part of your id filter parameters. For example:

 query {
    queryCart(filter{
      id: ["UUID2098", "UUID92083", "UUID98332", "UUID2833"]
    }){
      id
      totalPrice
      numberOfItems
    }
 }

To create a multi-parameter filter, you can use the and keyword to concatenate the filter requirements onto your query. In the query below, we are looking at a list of completed carts where the total purchase order is over $150.00.

 query {
    queryCart(filter{
      id: ["UUID2098", "UUID92083", "UUID98332", "UUID2833"]
    },
    and: {
      totalPrice: {
        gt: 150.00
      }
    }){
      id
      totalPrice
      numberOfItems
    }
 }

But what if you have a list of objects under a parent item that you want to filter? That is, filter down the nested values to only what you want.

To do this, you can create a nested filter in GraphQL to get to your required results.

In the example below, we want to query a specific completed cart based on the UUID and filter the cart to return items that have a greater price than $15 and have a discounted status of true. Here is the example syntax:

 query {
    queryCart(filter{
      id: "UUID2098"
    }){
      id
      totalPrice
      numberOfItems
      cartItems(filter: {
        price: {
            gt: 15.00
        }, and: {
          discount: true
        }
      })
    }
 }

In the previous examples, we’ve been filtering based on a definite value. What if we want to filter in GraphQL based on a range? To do this, you can use the between keyword.

In the example below, we want to query all our completed orders based on the number of items ordered. The filter parameters here are any that are ordered between 5 to 15 items per order. Here is an example of the GraphQL between syntax:

 queryCart(filter {numberOfItems: between: {min: 5, max:15}}){
    id
    userId
    totalPrice
 }

It’s also good to note that for this to work, you need to implement @search on your schema. For example, based on the above query, you’ll need the following schema:

type Cart{
 numberOfItems: Int @search
 id: String
 userId: String
 TotalPrice: Double
}

max and min values also work for alphabet-based filtering. It works based on alphabetical ordering.

In the example below, we have created a GraphQL query filter that will return all customers that have last names that begin with ‘Ca’ all the way to ‘Co’. For example:

queryCustomer(filter: {lastName: between: {min: 'Ca', max: 'Co'}}){
 firstName
 LastName
}

Another scenario for filtering in GraphQL that can come in useful is when you need to find objects that have one or more specified values. For example, you might want to filter your customer orders based on a specific postal code area.

Here is an example for the query’s syntax:

query{
  postalCode(filter: {code: {in: ["0600", "0601", "0602"]}}){
     code
     orderId
     customerDetails
  }
}

How is this different from just conducting a normal filter query? This is because the above filter aims to return data based on a parameter that is not usually the main id item such as cartId or customerId. Also attached to the postalCode parameter may also include other details such as suburb and city . The postalCode value is its own ‘parent’ value that’s being used as a child in a nested data object.

Finally, how do we filter non-null fields? The GraphQL trick is to use has. This will exclude values that are null. For example, you might have orders with no contact phone number attached to them. You want to be able to see only orders with phone numbers because there is a higher chance of it being a higher value order.

Here is the syntax for using has in GraphQL:

queryOrder(filter: {has: contactNumber}){
  orderId
  shippingAddress
  contactNumber
}

For the above query to work, you need to omit ! from your schema. In the example below, orderId, and shippingAddress cannot be empty as indicated by the ! after the value’s type. contactNumber however, has the option to be empty and not filled out by the user, and therefore contains the value null.

type Order{
  orderId: ID!
  shippingAddress: String!
  contactNumber: Int
}

Where to from here

Filtering is one way to get the query results you want in GraphQL. This leads to the question: where to from here? Getting comfortable with filtering in GraphQL is a good starting point, but there is more to it than just creating such queries.

Beyond searching and creating queries through filtering, there are also the following types of queries in GraphQL:

  • aggregate queries – where aggregated data is fetched
  • persistent queries – where the client sends hash queries to the server. Persistent queries are good for long-term performance and security because they reduce bandwidth utilization.
  • And, Or, and Not operators for GraphQL
  • Cached results to reduce server costs on complex queries
  • Order and pagination to segment the data
  • @cascade, @skip and @include directives

The above-suggested topics make a good Google checklist to help you find your way around the different parts of querying in GraphQL. While it is only the tip of what GraphQL can do, it is more than enough to get you started and give you all the things you need to achieve your querying needs.

About the author

Aphinya is a full-stack developer specializing in a range of technologies. In addition to contributing regularly on TabNine as a tech writer, she also runs dottedsquirrel.com