GraphQL Queries and Nodes
Relevant source files
The following files were used as context for generating this wiki page:
Seaography provides a dynamic system for mapping SeaORM entities to GraphQL nodes and queries. By leveraging the dynamic schema engine of async-graphql, it transforms database schemas into a fully-typed GraphQL API. This approach avoids heavy code generation while maintaining type safety and providing rich query capabilities including filtering, pagination, and relational nesting.
Sources: README.md:10-18, src/lib.rs:10-18
Schema Architecture and Root Query
The GraphQL schema in Seaography is built using a Builder and a BuilderContext. The query_root.rs file (typically generated or manually implemented) serves as the entry point for the GraphQL service, defining how the schema is initialized and how database connections are integrated into the execution context.
Schema Generation Flow
The schema generation process involves initializing a Builder, registering entity modules, and optionally configuring limits for query depth and complexity.
This diagram illustrates the typical lifecycle of schema construction within the query_root module.
Sources: generator/src/writer.rs:75-103, examples/sqlite/src/query_root.rs:21-65
Core Components of Query Root
| Component | Description |
|---|---|
Builder | The main engine responsible for converting SeaORM metadata into GraphQL types. |
BuilderContext | Holds configuration for naming conventions, lifecycle hooks, and type mapping. |
schema_builder | Function that orchestrates the registration of entities, enums, and custom operations. |
DatabaseConnection | Passed into the schema to be used as data context by resolvers. |
Sources: generator/src/writer.rs:88-100, examples/sqlite/src/query_root.rs:13-33
GraphQL Nodes and Relational Mapping
Every SeaORM entity is mapped to a GraphQL Object (Node). These nodes include fields for every database column and additional fields representing relationships (1-to-1, 1-to-N, M-to-N).
Entity Registration Logic
Entities are registered using the register_entity macro or functional API. This process defines the fields and the dataloaders required for efficient relationship fetching.
Field Customization
Seaography allows for extensive customization of how fields are presented in GraphQL:
- Naming Conventions: Supports boxable functions to transform entity names (e.g.,
singular,to_upper_camel_case) and column names (e.g.,to_snake_case). - Type Overrides: Specific columns can have their GraphQL types or conversion logic overridden using
ColumnOptions.
Sources: examples/sea-draw/src/schema.rs:25-50, examples/sea-draw/src/schema.rs:83-95
Query Features
Seaography queries support advanced features that mirror SeaORM's query capabilities.
Filtering and "Having" Clauses
Queries support complex filtering using operators like eq, gt, lt, and contains. Version 2.0 introduced the having clause for filtering parent entities based on the properties of related entities.
{
country(having: { city: { city: { eq: "London" } } }) {
nodes {
country
}
}
}
Sources: CHANGELOG.md:12-25, examples/sqlite/tests/query_tests.rs:1040-1071
Pagination Strategies
Two types of pagination are provided for all entity queries:
- Offset-based: Uses
pageandlimit. IncludespaginationInfo(current page, total pages). - Cursor-based: Uses
cursorandlimit. Follows the Relay specification withedges,node, andpageInfo(startCursor, endCursor, hasNextPage).
Sources: README.md:92-125, examples/sqlite/tests/query_tests.rs:136-224
Custom Queries and Mutations
While Seaography automatically generates queries for SeaORM entities, developers can extend the schema with custom operations using the #[CustomFields] macro.
Defining Custom Operations
Custom implementation blocks allow for manual resolver logic, which can then be registered with the schema builder.
#[CustomFields]
impl Operations {
async fn foo(_ctx: &Context<'_>, username: String) -> async_graphql::Result<String> {
Ok(format!("Hello, {}!", username))
}
}
Sources: CHANGELOG.md:32-47, examples/sqlite/src/query_root.rs:59-61
Configuration Options for Queries
| Option | Default | Description |
|---|---|---|
DEPTH_LIMIT | None | Restricts the maximum nesting level of a GraphQL query. |
COMPLEXITY_LIMIT | None | Restricts the total complexity score of a query. |
default_limit | 100 | Default number of records returned if pagination is omitted. |
max_limit | 500 | Maximum allowed value for the pagination limit argument. |
Sources: generator/src/templates/axum.rs:30-36, examples/sea-draw/src/schema.rs:98-99
Summary
GraphQL Queries and Nodes in Seaography represent a bridge between SeaORM's relational model and the dynamic requirements of a GraphQL API. The system automates the repetitive task of mapping columns and relations while providing hooks for security (guards), performance (dataloaders), and extensibility (custom queries). Through the Builder and BuilderContext, developers can fine-tune the resulting schema to meet specific application requirements.
Sources: README.md:10-25, src/lib.rs:204-230