Use table search
View as MarkdownOnce a table has a valid search plan, the generated surface exposes the same term through its ordinary callers.
Use the generated callers
Section titled “Use the generated callers”- The table toolbar sends the current term with its row request.
GET /api/tables/<table>?q=<term>searches the generated list route.GET /api/tables/<table>/export.csv?q=<term>applies the same search to CSV export.fetchTableRows({ tableName, search })serializessearchasq.- The CLI uses
pnpm exec sapporta rows list <table> --q "<term>".
The metadata endpoint exposes only "searchable": true or "searchable": false
to the browser. The recursive plan remains on the server.
Generated handlers retrieve the compiled plan from the loaded table catalog.
They own the q HTTP parameter; scopedRows() deliberately does not.
Search in application server code
Section titled “Search in application server code”When an application contract accepts a search term, compile the plan into a Drizzle predicate and pass it to the bounded read that fits the result:
import { buildSearchPredicate, scopedRows } from "@sapporta/server";
const rows = scopedRows(db, auth, books);const searchWhere = buildSearchPredicate( catalog.searchPlanFor(books.sqlName), "blue", auth,);const result = await rows.page({ where: searchWhere, page: 1, limit: 50,});The same predicate can narrow findMany() or scan(). The row helper still
adds request visibility. Calls without search, including count() and
countBy(), need no search plan.
A generated-style HTTP adapter can pass its parsed query to resolvePageQuery()
or resolveExportQuery(), which resolve q, filters, columns, and ordering.
Most application routes can reuse catalog.searchPlanFor() with
buildSearchPredicate() instead.
Keep search in URL state
Section titled “Keep search in URL state”Generated table screens store the term in the page URL:
/tables/books?q=blueFilters, sort, and pagination can live beside it:
/tables/books?filter[status][eq]=in_print&q=blue&sort=title&page=1Changing the term returns to the first page while preserving the rest of the table-query model. The recipient of a shared URL still sees only rows and relationship values allowed by their own request authority.
Search on /_lookup is separate. Lookup q filters the fields displayed by a
foreign-key picker; it does not use recursive table search. Grouped /_count
also does not accept table search.