GraphQL Initialization
Relevant source files
The following files were used as context for generating this wiki page:
GraphQL initialization in the SeaORM Pro framework involves setting up a dynamic schema based on database entities, configuring query constraints, and registering handlers for the GraphQL Playground and API requests. The system utilizes async-graphql and seaography to bridge the gap between SeaORM models and a functional GraphQL endpoint.
The initialization process is primarily driven by the GraphQLInitializer which executes during the application boot sequence. It constructs a schema using the project's database connection and caches it in a shared state for use by controllers.
Sources: src/initializers/graphql.rs:13-25, src/app.rs:43-47
Architecture and Initialization Flow
The initialization sequence starts within the App::initializers hook, where the GraphQLInitializer is registered. During the after_routes phase of the lifecycle, the system builds the async_graphql::dynamic::Schema and inserts it into the AppContext shared store.
The flow demonstrates how the schema is constructed from database entities before being made available to the application state.
Sources: src/app.rs:43-47, src/initializers/graphql.rs:18-27
Schema Construction
The schema is built using a Builder from seaography. It requires a BuilderContext, which defines lifecycle hooks, and the active DatabaseConnection. Entities are registered via a generated register_entity_modules function, ensuring the GraphQL schema stays in sync with the database models.
Sources: src/graphql/query_root.rs:25-30, examples/axum_example/api/src/graphql/query_root.rs:16-20
Key Components and Configuration
Initialization Constants
The system enforces safety limits on GraphQL queries to prevent resource exhaustion. These are defined during the schema construction phase.
| Configuration | Value | Description |
|---|---|---|
DEPTH | Some(100) | Maximum nesting depth allowed in a single GraphQL query. |
COMPLEXITY | Some(1000) | Maximum complexity score allowed for a query. |
| Initializer Name | "graphql" | Identifier used by the framework for this specific initializer. |
Sources: src/initializers/graphql.rs:8-16
GraphQL Handlers and Routes
The initialization process also involves setting up routes to serve the GraphQL API and its interactive playground.
This diagram illustrates the request-response flow for a standard GraphQL query processed through the initialized schema.
Sources: src/controllers/graphql.rs:46-55, examples/axum_example/api/src/lib.rs:271-285
Security and Middleware
Authentication Integration
GraphQL requests are typically intercepted by authentication middleware. The graphql_handler extracts user information from a JWT and injects a UserContext into the GraphQL request data, allowing for field-level authorization or ownership checks.
Sources: src/controllers/graphql.rs:27-41
Read-only Extensions
In specific environments (such as a demo site), the initialization can include a Readonly extension. This extension inspects the ExecutableDocument during the query parsing phase and returns an error if a Mutation operation is detected.
#[async_trait::async_trait]
impl Extension for ReadonlyExtension {
async fn parse_query(
&self,
ctx: &ExtensionContext<'_>,
query: &str,
variables: &Variables,
next: NextParseQuery<'_>,
) -> ServerResult<ExecutableDocument> {
let document = next.run(ctx, query, variables).await?;
if *DEMO_SITE {
let is_mutation = document.operations.iter().any(|(_, op)|
matches!(op.node.ty, OperationType::Mutation));
if is_mutation {
return Err(ServerError::new("Demo Site is Readonly", None));
}
}
Ok(document)
}
}
Sources: src/graphql/query_root.rs:56-74
Summary
GraphQL Initialization in this project is a structured process that leverages seaography to dynamically map SeaORM entities to an async-graphql schema. By utilizing the loco-rs initializer pattern, the project ensures that the schema is built with appropriate depth and complexity limits and is securely accessible via authenticated Axum handlers. This architecture provides a robust foundation for both the Admin Panel's data requirements and external API consumers.