Graphql (oridecon-graphql)
GraphQL support for Oridecon Framework — Strawberry, Apollo Federation, and subscriptions.
Overview
Section titled “Overview”oridecon-graphql provides a complete GraphQL layer built on Strawberry, with field-level permissions, DataLoaderProtocol batching for N+1 query elimination, WebSocket subscriptions, depth/complexity limiting, persisted queries, and automatic playground disable in production. All services are wired through Oridecon’s DI container.
Full documentation: docs.oridecon.dev
Install
Section titled “Install”uv add oridecon oridecon-web oridecon-graphql# Optional extrasuv add "oridecon-graphql[starlette]" # Starlette integrationuv add "oridecon-graphql[subscriptions]" # WebSocket subscriptionsQuick Start
Section titled “Quick Start”from oridecon import Applicationfrom oridecon.di.module import Module, modulefrom oridecon.graphql import GraphQLModulefrom oridecon.web import WebModule
import strawberry
@strawberry.typeclass Query: @strawberry.field def hello(self) -> str: return "world"
@module( imports=[ WebModule.configure(host="127.0.0.1", port=8000), GraphQLModule.configure(query_class=Query), ])class AppModule(Module): pass
async def main() -> None: async with Application.boot(modules=[AppModule]) as app: web = await app.container.resolve(WebProvider) web.run_server(host="127.0.0.1", port=8000)
if __name__ == "__main__": import asyncio
asyncio.run(main())GraphQL endpoint: http://127.0.0.1:8000/graphql
Playground: http://127.0.0.1:8000/graphql/playground (development only)
Configuration
Section titled “Configuration”Zero-config usage: Call
GraphQLModule.configure()with no arguments to use all defaults.
Option 1 — YAML file
Section titled “Option 1 — YAML file”graphql: server: path: "/graphql" debug: false playground: enabled: true schema: max_depth: 10 complexity_limit: 1000Option 2 — Profiles + Environment Variables (recommended)
Section titled “Option 2 — Profiles + Environment Variables (recommended)”export ORI_GRAPHQL__PATH=/api/graphqlexport ORI_GRAPHQL__DEBUG=trueexport ORI_GRAPHQL__DEPTH_LIMIT__MAX_DEPTH=8Option 3 — Python
Section titled “Option 3 — Python”from oridecon.graphql import GraphQLModulefrom oridecon.graphql.config import GraphQLConfig
config = GraphQLConfig.development()GraphQLModule.configure(config=config, query_class=Query)Config reference
Section titled “Config reference”| Field | Default | Env var | Description |
|-------|---------|---------|-------------|
| path | "/graphql" | ORI_GRAPHQL__PATH | GraphQL HTTP endpoint |
| debug | false | ORI_GRAPHQL__DEBUG | Propagates to errors.debug_mode |
| introspection.enabled | true | ORI_GRAPHQL__INTROSPECTION__ENABLED | Disabled automatically in production |
| playground.enabled | true | ORI_GRAPHQL__PLAYGROUND__ENABLED | Disabled automatically in production |
| playground.path | "/graphql/playground" | ORI_GRAPHQL__PLAYGROUND__PATH | Playground URL |
| subscriptions.enabled | true | ORI_GRAPHQL__SUBSCRIPTIONS__ENABLED | WebSocket subscriptions |
| subscriptions.path | "/graphql/ws" | ORI_GRAPHQL__SUBSCRIPTIONS__PATH | WebSocket endpoint |
| depth_limit.enabled | true | ORI_GRAPHQL__DEPTH_LIMIT__ENABLED | Enable query depth limiting |
| depth_limit.max_depth | 10 | ORI_GRAPHQL__DEPTH_LIMIT__MAX_DEPTH | Maximum allowed query depth |
| complexity.enabled | true | ORI_GRAPHQL__COMPLEXITY__ENABLED | Enable complexity scoring |
| complexity.max_complexity | 1000 | ORI_GRAPHQL__COMPLEXITY__MAX_COMPLEXITY | Maximum complexity score |
| dataloader.enabled | true | ORI_GRAPHQL__DATALOADER__ENABLED | Enable DataLoaderProtocol integration |
| dataloader.batch_delay_ms | 2.0 | ORI_GRAPHQL__DATALOADER__BATCH_DELAY_MS | Batch accumulation delay (ms) |
| persisted_queries.enabled | true | ORI_GRAPHQL__PERSISTED_QUERIES__ENABLED | Automatic persisted queries (APQ) |
| cache.enabled | true | ORI_GRAPHQL__CACHE__ENABLED | Response caching |
| errors.mask_errors | true | ORI_GRAPHQL__ERRORS__MASK_ERRORS | Mask internal errors in responses |
| schema_baseline_path | null | ORI_GRAPHQL__SCHEMA_BASELINE_PATH | SDL file for breaking-change detection |
Module Factory Methods
Section titled “Module Factory Methods”| Method | Description |
|--------|-------------|
| GraphQLModule.configure(...) | Configure with explicit config and query class |
| GraphQLModule.stub() | Minimal config for testing |
Key Features
Section titled “Key Features”- Strawberry GraphQL — schema-first GraphQL with type annotations
- DataLoaderProtocol batching — eliminates N+1 queries with per-request caching
- WebSocket subscriptions —
graphql-transport-wsprotocol support - Depth and complexity limiting — prevents malicious or expensive queries
- Field-level permissions —
AbstractPermissionsubclassing for fine-grained access - Automatic persisted queries (APQ) — reduces payload size for repeated queries
- Schema baseline checking — detect breaking changes at boot via SDL comparison
Testing
Section titled “Testing”from oridecon import Applicationfrom oridecon.graphql import GraphQLModule
async with Application.boot(modules=[GraphQLModule.stub()]) as app: executor = await app.container.resolve(GraphQLExecutorProtocol) assert executor is not NoneKey Source Files
Section titled “Key Source Files”| File | What it contains |
|------|----------------|
| src/oridecon/graphql/module.py | GraphQLModule.configure(), .stub() |
| src/oridecon/graphql/config.py | GraphQLConfig and all sub-configs |
| src/oridecon/graphql/di/provider.py | GraphQLProvider boot and registration |
| src/oridecon/graphql/security/permissions.py | AbstractPermission base class |
| src/oridecon/graphql/dataloader/loader.py | DataLoaderProtocol implementation |
| src/oridecon/graphql/decorators.py | @retry_resolver, @log_resolver |