NewWe open-sourced 50+ Laravel packages
Custom AI apps, agents and automation — Roundly ConsultingRoundly
All packages

The package sits between untrusted query strings and your database, so the dangerous parts are designed out rather than left to each endpoint:

  • Allow-list by default — nothing is filterable or sortable unless declared; anything else is an HTTP 400 (or dropped in ignore mode). A mistyped mode config throws InvalidConfigurationException rather than guessing.
  • Operators never come from raw input — operator() fixes the comparison in code; operators() honours only the tokens you declared and treats anything else as a literal value.
  • Bound values, developer identifiers — built-in filters bind every value as a parameter; column identifiers come from your declarations and are wrapped by the query grammar, never from the request.
  • Wildcards can’t widen a search — %, _ and \ in user input are escaped and matched with an explicit ESCAPE clause on every driver.
  • Bounded work — limits.max_filter_values, limits.max_value_length and limits.max_sorts cap what a single URL can ask for; duplicate sort columns are removed.
  • No argument injection into scopes — a scope receives exactly one request-controlled argument unless you opt into spread: true.
  • Capped reflection — error messages echo at most 5 unknown keys, each truncated to 64 characters.
  • Typed columns stay safe — a FilterValueShape keeps malformed uuids and ids away from PostgreSQL, so a bad value is an empty result, not a 500.
  • Validated page size — per_page above the maximum is a 422, and perPage() hard-caps it again.
  • Public names, private columns — internal names keep your schema out of the URL.

Correct negations

Negations mean what a person filtering a list means: not and ncontains include NULL rows, a multi-value negation reads as “none of these” (AND, not OR), and relation negations use whereDoesntHave, so a row related to an excluded value is dropped even when it has other relations.

Show your open-source love

This package is free and MIT-licensed. If it saves you time, a one-off donation or a Patreon membership keeps it maintained, tested and documented.

More ways to support, including crypto

By donating, you agree to our donation terms.

Want this built into your product?

We integrate our packages into custom Laravel and AI builds. Tell us what you're working on and we'll reply within 48 hours.