Pagination & Advanced Queries
Relevant source files
The following files were used as context for generating this wiki page:
Loco provides a robust framework for handling data interactions, emphasizing productivity through high-level abstractions over database operations. By leveraging SeaORM, Loco allows developers to model business entities with rich relations and validation while avoiding direct SQL writing. The system supports complex query patterns, including filtering and automated entity management, to ensure maintainability and performance.
The querying architecture is integrated into the model layer, allowing for clean separation of concerns. Developers can implement custom search logic, such as finding users by email or generating reports, directly within the model implementation. This approach ensures that the database layer remains the single source of truth for data access patterns.
Sources: docs-site/config.toml:92-100, docs-site/content/blog/hello-world.md:21-25
Model-Driven Querying
Loco utilizes SeaORM as its primary database abstraction layer. Models are defined as rich entities that encapsulate both the data structure and the logic required to interact with that data. This includes relations, validations, and custom query methods.
Database Interaction Flow
The following diagram illustrates how a controller initiates a query through the model layer to interact with the database.
Key Query Components
Queries in Loco typically involve the following components:
- Entity Models: Rust structures representing database tables.
- Query Builders: DSL-based methods provided by SeaORM (e.g.,
.filter(),.one(),.all()). - AppContext: Provides the necessary database connection string and environment settings.
| Component | Description |
|---|---|
find_by_id | Standard method to retrieve a single entity by its primary key. |
filter | Applies conditional logic (e.g., eq(Column::Email, email)) to restrict results. |
one(db) | Executes a query and returns a single record or an error. |
all(db) | Executes a query and returns a collection of all matching records. |
| Sources: docs-site/config.toml:95-108, docs-site/config.toml:118-125 |
CLI for Data Management
Loco provides a powerful Command Line Interface (CLI) to manage database schemas and entities. This is crucial for maintaining the "Advanced Query" capabilities as it ensures the Rust entities remain in sync with the underlying database structure.
Entity Generation and Migration
The CLI automates the creation of migration files and the subsequent generation of Rust entity code based on the database schema.
Sources: DEVELOPMENT.md:27-38, src/cli.rs:365-408
CLI Database Commands
| Command | Action |
|---|---|
db create | Creates the physical database. |
db migrate | Applies pending migrations to the schema. |
db down | Rolls back the last migration(s). |
db reset | Drops all tables and reapplies all migrations. |
db seed | Populates the database with initial data from fixtures. |
| Sources: src/cli.rs:461-496, DEVELOPMENT.md:27-31 |
Advanced Configuration for Asset Serving
Loco allows for advanced routing configurations, including the separation of API endpoints and static assets. This is often used when a Loco backend serves a client-side frontend (e.g., React/Vite).
Routing and Prefixes
Developers can group advanced queries under specific URL prefixes, such as /api, to distinguish them from static content delivery.
pub fn routes() -> Routes {
Routes::new()
.prefix("notes")
.add("/{id}", get(get_one))
}
Sources: docs-site/config.toml:127-131, docs-site/content/blog/frontend-website.md:73-78
Static Middleware Configuration
Advanced querying environments often require serving static files with fallbacks for Single Page Applications (SPAs).
| Option | Type | Description |
|---|---|---|
enable | Boolean | Activates the static asset middleware. |
must_exist | Boolean | Ensures the source folder exists before starting. |
folder.path | String | The filesystem path to the assets (e.g., frontend/dist). |
fallback | String | The file served when no specific route matches (e.g., index.html). |
| Sources: docs-site/content/blog/frontend-website.md:88-96, src/cli.rs:511-525 |
Background Tasks and Reporting
For queries that are too intensive for a standard request-response cycle, Loco supports background jobs. These jobs can access the AppContext to perform complex database aggregations or generate large reports asynchronously.
Worker Interaction
Workers implement the Worker trait, defining a perform function that executes the query logic in the background.
impl worker::Worker<DownloadArgs> for UsersReportWorker {
async fn perform(&self, args: DownloadArgs) -> worker::Result<()> {
let all = Users::find()
.all(&self.ctx.db)
.await
.map_err(Box::from)?;
// Process data...
Ok(())
}
}
Sources: docs-site/config.toml:144-155, docs-site/config.toml:103-107
Summary
Pagination and advanced queries in Loco are handled through a combination of SeaORM entities for data logic, a powerful CLI for schema management, and Background Workers for long-running data tasks. By strictly defining entities and using the generated query builders, Loco ensures that database interactions are safe, performant, and maintainable. This structure supports a "one-person framework" philosophy where complex data operations are simplified through automation and strong typing.
Sources: docs-site/content/blog/hello-world.md:65-75, DEVELOPMENT.md:33-38