Filtering and Sorting Through GraphQL

Production GraphQL APIs commonly need filtering and sorting capabilities.

A simple schema might expose:

input UserFilterInput {
  search: String
  isActive: Boolean
}

enum UserSortField {
  CREATED_AT
  NAME
}

enum SortDirection {
  ASC
  DESC
}

input UserSortInput {
  field: UserSortField!
  direction: SortDirection!
}

The query could be:

users(
  filter: UserFilterInput
  sort: UserSortInput
): UserConnection!

The resolver translates the API-level filter into a database query.

For example:

const mongoFilter = {};

if (filter?.isActive !== undefined) {
  mongoFilter.isActive = filter.isActive;
}

Search requires additional consideration. A naive MongoDB regular expression across large collections can become expensive.

Production search may require:

  • appropriate MongoDB indexes
  • text indexes
  • Atlas Search
  • normalized search fields
  • external search systems

GraphQL should define a clean API contract while the repository chooses an efficient implementation.

Filtering Architecture
GraphQL input: Typed filter object
Provides a predictable API contract.
Service: Business-level filtering rules
Determines which filters are allowed and how they interact.
Repository: Database query
Translates approved filters into MongoDB operations.
Key Takeaways
  • Filtering should use explicit GraphQL input types.
  • The API layer should not expose arbitrary MongoDB operators.
  • Search performance depends on the underlying index strategy.
  • GraphQL provides the contract while the repository implements the query.
Knowledge Check

Why should a GraphQL API avoid accepting arbitrary MongoDB query operators directly from clients?