Fetcher Service Kind
Overview
Fetchers are data retrieval services that provide a standardized interface for querying database entities. They implement a consistent pattern for filtering, pagination, and result retrieval across all domain models.
Architecture
Core Components
Base Fetcher Library (src/lib/fetcher/)
- Fetcher struct: Core database query builder and executor
- FetcherMod: Query modification object containing filters, pagination, and ordering
- Filter types: Various filter implementations for different data types and operations
Entity-Specific Fetchers (src/srv/fetchers/)
- Each domain model has its own dedicated fetcher (e.g., GardenFetcher, UserFetcher)
- All fetchers follow the same interface pattern and method conventions
- Integrated with corresponding Table services for data mapping
Key Structures
FetcherMod
Query configuration object that controls:
- Pagination: Page, PerPage, Paginated fields
- Filtering: Collection of filter objects
- Ordering: OrderBys and DefaultOrder configurations
- Result limiting: One flag for single record queries
- Counting: Count flag for count-only queries
Filter Types
ExactStringValueFilter: Exact string matchingContainsStringValueFilter: String contains matching with LIKEExactIntegerValueFilter: Integer equalityExactBooleanValueFilter: Boolean matchingAbsentValueFilter: NULL value filteringInStringValuesFilter: IN clause for multiple valuesNotInStringValuesFilter: NOT IN clause- And more specialized filter types
Standard Methods
Every entity fetcher implements these standard methods:
Query Methods
FindAll(ctx, mod) ([]*Entity, error) // All records with filtering
FindSet(ctx, mod) ([]*Entity, error) // Filtered set of records
FindSetIn(ctx, ids, mod) ([]*Entity, error) // Records with IDs in list
FindOne(ctx, mod) (*Entity, bool, error) // Single record with exists flag
FindOneById(ctx, id, mod) (*Entity, bool, error) // Single record by ID
Paginated Methods
FindPage(ctx, mod) ([]*Entity, *FetcherPagination, error) // Paginated results
FindPageIn(ctx, ids, mod) ([]*Entity, *FetcherPagination, error) // Paginated with ID filter
Must Methods (Panic on Error)
MustFindAll(ctx, mod) []*Entity
MustFindSet(ctx, mod) []*Entity
MustFindOne(ctx, mod) (*Entity, bool)
// ... and more Must* variants
Shall Methods (Must Exist)
ShallFindOne(ctx, mod) *Entity // Panics if not found
ShallFindOneById(ctx, id, mod) *Entity // Panics if not found by ID
Usage Examples
Basic Entity Retrieval
// Get all gardens
gardens, err := gardenFetcher.FindAll(ctx, nil)
// Get gardens with default modifiers
mod := gardenFetcher.Mod()
gardens, err := gardenFetcher.FindSet(ctx, mod)
Filtering
mod := gardenFetcher.Mod()
mod.ExactStringValueFilter("name", "My Garden")
mod.ContainsStringValueFilter("description", "vegetables")
gardens, err := gardenFetcher.FindSet(ctx, mod)
Pagination
mod := gardenFetcher.Mod()
mod.Page = 2
mod.PerPage = 10
gardens, pagination, err := gardenFetcher.FindPage(ctx, mod)
Ordering
mod := gardenFetcher.Mod()
mod.DescOrder("created_at")
mod.AscOrder("name")
gardens, err := gardenFetcher.FindSet(ctx, mod)
Integration with Tables
Fetchers work closely with Table services:
- Use Table.TableName() for SQL table identification
- Use Table.Columns() for SELECT field lists
- Use Table.EsoToEntity() for result mapping
- Use Table.EsoToPointers() for SQL scanning
SQL Query Building
The base Fetcher automatically builds SQL queries: - Handles complex WHERE clauses from filters - Manages ORDER BY from OrderBys configuration - Implements LIMIT/OFFSET for pagination - Supports COUNT queries for pagination totals - Uses parameterized queries for security
Error Handling
- Standard methods return errors for caller handling
- Must* methods panic on errors (using
lib.Poe()) - Shall* methods panic if records don’t exist
- No-row conditions return
(nil, false, nil)for optional queries
Configuration
Each fetcher provides a Mod() method returning default configuration:
- Default pagination settings (typically 25 per page)
- Default ordering (entity-specific, e.g., by name)
- Baseline filter configurations