Skip to content

Configuration

Customize FSPManager behavior with FSPConfig:

from fastapi_fsp import FSPConfig, FSPPresets

# Custom configuration
config = FSPConfig(
    max_per_page=50,
    default_per_page=20,
    strict_mode=True,  # Raise errors for unknown fields
    max_page=100,
    allow_deep_pagination=False,
)

# Or use presets
config = FSPPresets.strict()  # strict_mode=True
config = FSPPresets.limited_pagination(max_page=50)  # Limit deep pagination
config = FSPPresets.high_volume(max_per_page=500)  # High-volume APIs

# Apply configuration
@app.get("/heroes/")
def read_heroes(session: Session = Depends(get_session), fsp: FSPManager = Depends(FSPManager)):
    fsp.apply_config(config)
    return fsp.generate_response(select(Hero), session)

Search Backend Optimization

By default, tokenized search generates N tokens x M fields = N*M individual ILIKE conditions, each requiring a full table scan. For PostgreSQL, you can choose a faster search backend:

Backend SQL strategy Substring match? Indexable?
ILIKE (default) N*M individual ILIKEs Yes No (full scan)
TSVECTOR to_tsvector @@ to_tsquery Prefix only GIN index
TRIGRAM concat + N ILIKEs Yes GIN + pg_trgm

Key tradeoff: TSVECTOR is fastest (single expression) but only matches word prefixes — "media" matches "Medialaan" but "laan" does not. TRIGRAM preserves full substring semantics while reducing N*M to N operations.

from fastapi_fsp import FSPConfig, SearchBackend

# Use tsvector for fast prefix-matching search (PostgreSQL only)
config = FSPConfig(search_backend=SearchBackend.TSVECTOR)

# Use trigram for full substring search with fewer operations (PostgreSQL only)
config = FSPConfig(search_backend=SearchBackend.TRIGRAM)

# Limit maximum search tokens (default: 10)
config = FSPConfig(
    search_backend=SearchBackend.TSVECTOR,
    max_search_tokens=5,
)

@app.get("/heroes/")
def read_heroes(
    session: Session = Depends(get_session),
    fsp: FSPManager = Depends(FSPManager),
):
    fsp.apply_config(config)
    return fsp.generate_response(select(Hero), session)

Non-search OR groups (mixed operators, phrase mode, custom with_or_filters()) automatically fall back to the standard ILIKE path regardless of the configured backend.

Strict Mode

When strict_mode=True, FSPManager raises HTTP 400 errors for unknown filter/sort fields:

# With strict_mode=True, this raises HTTP 400:
# GET /heroes/?field=unknown_field&operator=eq&value=test
# Error: "Unknown field 'unknown_field'. Available fields: age, id, name, secret_name"