sqlx-paginated
A blazingly fast, type-safe, fluid query builder for dynamic APIs, offering seamless pagination, sorting and dynamic filtering on top of SQLx.
Table of Contents
- Features
- Database Support
- Market Analysis
- Installation
- Quick Start
- API Reference
- Query Examples
- Performance Considerations
- Security Features
- Contributing
- License
Features
Core Capabilities
- 🔍 Full-text search with column specification
- 📑 Smart pagination with customizable page size
- 🔄 Dynamic sorting on any column
- 🎯 Flexible filtering system
- 📅 Date range filtering
- 🔒 Type-safe operations
- 🔥 High performance
- 🛡️ SQL injection protection
Technical Features
- Builder patterns for query parameters and query construction
- Graceful error handling
- Logging with tracing (if enabled)
- Macro and function syntax support
Query Features
- Case-insensitive search
- Multiple column search
- Complex filtering conditions
- Date-based filtering
- Dynamic sort direction
- Customizable page size
- Result count optimization (opt-out of total records lookup ahead)
Database Support
Current vs Planned Support
| Database | Status | Version | Features | Notes |
|---|---|---|---|---|
| PostgreSQL | ✅ Supported | 12+ | All features supported | Ready |
| SQLite | 🚧 Planned | 3.35+ | Basic features planned | Development starting in Q1 2025 |
| MySQL | 🚧 Planned | 8.0+ | Core features planned | On roadmap |
⚠️ Note: This documentation covers PostgreSQL features only, as it's currently the only supported database.
Market Analysis
Ecosystem Gaps
-
Query builders
- Diesel: Full ORM, can be heavyweight
- SeaQuery: Generic and can be verbose
- sqlbuilder: Basic SQL building without pagination or security
-
Missing features in existing solutions
- Easy integration with web frameworks
- Automatic type casting
- Typesafe search/filter/sort/pagination capabilities
Unique Selling Points
- Quick Web Framework Integration with minimal footprint
Actix Web handler example
use ;
use ;
async
- Type Safety & Ergonomics for parameter configuration
let params = new
.with_pagination
.with_sort
.with_search
.build;
- Advanced Builder Patterns
- Optional fluent API for query parameters (QueryParams) which allow defining search, search location, date filtering, ordering, and custom filtering.
- Fluent API for the entire supported feature set, more here: advanced example
paginated_query_as!
.with_params
.with_query_builder
Target Audience
-
Primary users
- Rust web developers or API teams
- Teams needing quick and secure query building
- Projects requiring pagination and dynamic filtering APIs
- SQLx users wanting higher-level abstractions for repetitive tasks
-
Use cases
- REST APIs with pagination
- Admin panels
- Data exploration interfaces
Installation
Add to Cargo.toml:
[]
= { = "0.2.29", = ["postgres"] }
Quick Start
Basic Usage
/// Macro usage example
async
Response Example
API Reference
Pagination Parameters
| Parameter | Type | Default | Min | Max | Description |
|---|---|---|---|---|---|
| page | integer | 1 | 1 | n/a | Current page number |
| page_size | integer | 10 | 10 | 50 | Number of records per page |
Example:
GET /v1/internal/users?page=2&page_size=20
Sort Parameters
| Parameter | Type | Default | Allowed Values | Description |
|---|---|---|---|---|
| sort_column | string | created_at | Any valid table column | Column name to sort by |
| sort_direction | string | descending | ascending, descending | Sort direction |
Example:
GET /v1/internal/users?sort_column=last_name&sort_direction=ascending
Search Parameters
| Parameter | Type | Default | Max Length | Description |
|---|---|---|---|---|
| search | string | null | 100 | Search term to filter results |
| search_columns | string | name,description | n/a | Comma-separated list of columns |
Example:
GET /v1/internal/users?search=john&search_columns=first_name,last_name,email
Date Range Parameters
| Parameter | Type | Default | Format | Description |
|---|---|---|---|---|
| date_column | string | created_at | Column name | Column to filter on |
| date_after | datetime | null | ISO 8601 | Start of date range |
| date_before | datetime | null | ISO 8601 | End of date range |
Example:
GET /v1/internal/users?date_column=created_at&date_after=2024-01-01T00:00:00Z
Filtering Parameters
| Parameter | Type | Default | Max Length | Description |
|---|---|---|---|---|
| * | string,boolean,datetime | null | 100 | Any valid table column for given struct |
Example:
GET /v1/internal/users?confirmed=true
Query Examples
- Given the following
struct, we can then perform search and filtering against its own fields. - We should also receive a paginated response back with the matching records.
-
Combined search, sort, date range, pagination and custom filter
- Notice the
confirmed=truefilter.
Request:
GET /v1/internal/users
?search=john
&search_columns=first_name,last_name,email
&sort_column=created_at
&sort_direction=descending
&date_before=2024-11-03T12:30:12.081598Z
&date_after=2024-11-02T12:30:12.081598Z
&page=1
&page_size=20
&confirmed=true
Response:
-
Date range filter combined with two other custom filters
- Notice the
confirmed=trueandfirst_name=Alexfilters. - For the
first_namefilter the value will be an exact match (case-sensitive). - You can extend your struct as you please while the query parameters will also be available automatically.
Request:
GET /v1/internal/users
?date_before=2024-11-03T12:30:12.081598Z
&date_after=2024-11-02T12:30:12.081598Z
&confirmed=true
&first_name=Alex
Response:
Performance Considerations
Query Pattern Optimization
| Query Pattern | Impact | Recommendation |
|---|---|---|
| SELECT * | ❌ High Impact | Specify needed columns |
| Large Text Columns | ❌ High Impact | Use separate detail endpoint |
| Computed Columns | ⚠️ Medium Impact | Cache if possible |
| JSON Aggregation | ⚠️ Medium Impact | Limit array size |
Recommended Indexes
-- Text search
(to_tsvector('english', name));
-- Composite indexes for common queries
(confirmed, created_at);
-- JSON indexes
(metadata);
Pagination Performance
| Page Size | Records | Performance Impact |
|---|---|---|
| 1-10 | Optimal | ✅ Best |
| 11-50 | Good | ✅ Good |
| 51-100 | Caution | ⚠️ Monitor |
| 100+ | Poor | ❌ Not Recommended |
Security Features
Input Sanitization
- Search terms are cleaned and normalized
- Parameter input values are trimmed and/or clamped against their defaults
- Column names are validated against an allowlist:
- The struct itself first;
- Database specific table names second;
- SQL injection patterns are blocked
- System table access is prevented
Protected Patterns
- System schemas (pg_, information_schema)
- System columns (oid, xmin, etc.)
- SQL injection attempts
- Invalid characters in identifiers
Contributing
I warmly welcome contributions from the community! If you have ideas, improvements, or fixes, we encourage you to submit a Pull Request. Your input is highly valued, and I'm excited to collaborate with you to make this project even better.
License
This project is licensed under the MIT License - see the LICENSE file for details.