Back to Blog
Lesson 22 of the GraphQL: Your First GraphQL Schema & Server course
API ArchitectureAugust 9, 20263 min read

Filtering Data with Arguments: Dynamic GraphQL Resolvers

Learn how to implement filtering in your GraphQL resolvers using arguments. Master the logic to transform broad data collections into precise, requested results.

GraphQLResolversFilteringArgumentsJavaScriptAPI Design
Scrabble tiles spelling 'Improve Your Argument' on a green background with leaves.

Previously in this course, we explored the Introduction to Resolver Arguments: Making GraphQL Dynamic, where we covered the syntax for passing data from the client to your server. In this lesson, we are going to take that foundation and apply it to a practical, real-world scenario: Filtering.

Up until now, our resolvers have largely returned static data or complete lists. However, a production API must allow clients to request specific slices of data. Using arguments for identification and filtering is the primary way we make our services truly useful.

The Philosophy of Filtering

In GraphQL, the server doesn't "decide" what to return based on global state; it decides based on the args provided by the client. Think of a resolver as a function:

  1. Input: The args object containing filters (e.g., id, category, status).
  2. Logic: JavaScript array methods like .find() or .filter().
  3. Output: A specific subset of your data collection.

By implementing this, you move from a static data provider to an interactive API.

Worked Example: Filtering a Product List

Let’s advance our running project. Suppose we have a list of products and we want to allow users to fetch products by a specific category.

1. Defining the Schema

First, update your SDL to accept an argument in your query.

GraphQL
type Query {
  # We add the 'category' argument to our products field
  products(category: String): [Product]
}

2. Implementing the Filter Logic

In your resolver file, we will access the args parameter (the second argument of the resolver function) to perform the filtering.

JAVASCRIPT
const products = [
  { id: CE9178">'1', name: CE9178">'Keyboard', category: CE9178">'Electronics' },
  { id: CE9178">'2', name: CE9178">'Coffee Mug', category: CE9178">'Kitchen' },
  { id: CE9178">'3', name: CE9178">'Mouse', category: CE9178">'Electronics' }
];

const resolvers = {
  Query: {
    products: (_, args) => {
      // If no category is provided, return all products
      if (!args.category) {
        return products;
      }
      
      // Filter the collection based on the argument
      return products.filter(product => product.category === args.category);
    }
  }
};

Hands-on Exercise

Modify your existing books or users resolver to support a search by a specific property.

  1. Add an argument to your schema definition (e.g., author or role).
  2. Implement an if check inside your resolver to see if that argument exists.
  3. If it exists, use the .filter() method to return only matching records.
  4. Test your implementation in Apollo Sandbox by passing the argument in your query string.

Common Pitfalls

  • Case Sensitivity: When filtering strings, remember that 'electronics' === 'Electronics' is false. Always normalize your data using .toLowerCase() if you want your API to be user-friendly.
  • Returning Undefined: If your filter returns an empty array, that is valid GraphQL (it just returns []). However, ensure your resolver doesn't return undefined or null if the schema expects a list [Product].
  • Mixing Logic: Don't perform complex business logic inside the resolver. Keep your data source (the array or database) separate from your filtration logic.

Comparison: Find vs. Filter

MethodPurposeReturn Value
.find()Locating a single unique record (e.g., by ID)Object or undefined
.filter()Extracting a subset of a collectionArray

FAQ

Q: Can I use multiple filters at once? A: Yes. You can define multiple arguments in your SDL (e.g., products(category: String, inStock: Boolean)) and chain filter methods in your resolver.

Q: Should I filter on the client or the server? A: Always filter on the server. Filtering on the client forces the server to send unnecessary data (over-fetching), which negates the efficiency benefits we discussed in The Limitations of REST.

Recap

We've moved from static data retrieval to dynamic filtering by leveraging resolver arguments. By checking for the presence of an argument and applying standard JavaScript array methods, we can provide clients with exactly the data they need.

Up next: Handling Missing Arguments, where we’ll discuss how to set default values and handle null inputs gracefully.

Similar Posts