Skip to content
API Design Learn/Querying, Errors & Contracts
Browsing as a guest. Sign in to save your progress and earn XP as you complete chapters.

Filtering, Sorting & Search Query Params

6 min read

You'll learn to

  • -Design consistent query parameter conventions for filtering, sorting, and free-text search across a collection endpoint
  • -Keep query parameters additive and optional so existing clients never break when a new one is added

A collection endpoint like `/orders` almost never stays a plain "return everything" endpoint for long - clients need to filter by status, sort by date, and search by keyword. Query parameters are where that flexibility belongs, kept separate from the resource path itself so the resource identity (`/orders`) stays stable while the query shape evolves.

Filtering, sorting, and search as query parameters
GET /orders?status=shipped&sort=-created_at&q=laptop

# status=shipped        filter to orders with this status
# sort=-created_at       sort by created_at descending (- prefix = descending)
# q=laptop               free-text search across searchable fields

Consistent Conventions Matter More Than Any Single Choice

  • -Filtering: `field=value` for exact match is the simplest default; more complex filters (ranges, multiple values) need an explicit, documented convention - e.g. `price_min`/`price_max`, or `status=shipped,delivered` for an OR match.
  • -Sorting: a `sort` parameter with a field name, using a prefix (`-` for descending) or a separate `order` parameter - either works, but pick one convention and use it everywhere.
  • -Search: a single `q` parameter for free-text search is a widely recognized convention (matching how most search engines and APIs already work), rather than inventing a bespoke parameter name per endpoint.

Query Params Must Stay Additive

The single most important property of query parameters: adding a new one must never break a client that doesn't send it. This is what makes them the right place for optional refinements - a client written before `sort` existed keeps working exactly as before once `sort` is added, because omitting an optional parameter is always well-defined (fall back to a sensible default, like insertion or creation order).

A quick self-check for any new query parameter: "if a client never sends this, does the endpoint still behave sensibly?" If the answer requires the client to know about the new parameter to avoid broken behavior, it should probably not be a query parameter at all - reconsider it as part of a versioned change instead.

Interview Signal

The interviewer asks how you'd support "orders over $100, sorted by newest first" on `GET /orders`.

Weak Answer

"I'd add a new endpoint like `/orders/expensive-sorted` that returns exactly that."

Strong Answer

"I'd use query parameters on the existing collection endpoint: `GET /orders?price_min=100&sort=-created_at`. That composes with any other filter a client might already be using, rather than creating a new endpoint for every specific combination of filters someone might want - which would grow unboundedly as more combinations come up."

Check Yourself1 / 3

Why do filtering and sorting belong in query parameters rather than the resource path?

Ready to Build This?

Design The Query Master in the API Design Lab's REST Foundations act.

ScaleDojo Logo
Initializing ScaleDojo