reinhardt-graphql
GraphQL integration (facade crate)
Overview
GraphQL API support with schema generation from models, query and mutation resolvers, and integration with the authentication and permission system. Provides a flexible alternative to REST APIs.
This is a facade crate that re-exports functionality from the following modules:
- core: Core GraphQL implementation
- macros: Procedural macros for GraphQL (when features enabled)
Crate Structure
reinhardt-graphql/ (facade crate - public API)
├── crates/
│ ├── core/ (core GraphQL implementation)
│ └── macros/ (procedural macros)
Users should depend on `reinhardt-graphql` (this facade crate) for all GraphQL functionality.
Features
Implemented ✓
Core Type System
- GraphQL Type Markers:
GraphQLTypeandGraphQLFieldtraits for type-safe GraphQL type definitions - Error Handling: Custom
GraphQLErrorenum with Schema, Resolver, and NotFound variants - Base Resolver Trait: Async
Resolvertrait with generic output types for flexible resolver implementation
Schema & Data Types
- User Type: Complete GraphQL object implementation with id, name, email, and active fields
- User Storage: Thread-safe in-memory storage using
Arc<RwLock<HashMap>>for user datanew(): Create new storage instanceadd_user(): Add or update user in storageget_user(): Retrieve user by IDlist_users(): List all stored users
- Input Types:
CreateUserInputfor user creation mutations - Schema Builder:
create_schema()function to build GraphQL schema with data context
Query Operations
- User Queries:
user(id: ID): Retrieve single user by IDusers(): List all usershello(name: Option<String>): Simple greeting query for testing
- Context Integration: Queries access UserStorage through GraphQL context
Mutation Operations
- User Mutations:
createUser(input: CreateUserInput): Create new user with auto-generated UUIDupdateUserStatus(id: ID, active: bool): Update user active status
- State Management: Mutations persist changes to UserStorage
Subscription System
- Event Types:
UserEventenum supporting Created, Updated, and Deleted events - Event Broadcasting:
EventBroadcasterwith tokio broadcast channel (capacity: 100)new(): Create new broadcaster instancebroadcast(): Send events to all subscriberssubscribe(): Subscribe to event stream
- Subscription Root:
SubscriptionRootwith filtered subscription streamsuserCreated(): Stream of user creation eventsuserUpdated(): Stream of user update eventsuserDeleted(): Stream of user deletion events (returns ID only)
- Async Streams: Real-time event filtering using async-stream
Integration
- async-graphql Integration: Built on async-graphql framework for production-ready GraphQL server
- Type Safety: Full Rust type system integration with compile-time guarantees
- Async/Await: Complete async support with tokio runtime
- Documentation: Comprehensive doc comments with examples for all public APIs
gRPC Transport (Optional - graphql-grpc feature)
- GraphQL over gRPC Service:
GraphQLGrpcServiceimplementing gRPC protocol for GraphQLexecute_query(): Execute GraphQL queries via unary RPCexecute_mutation(): Execute GraphQL mutations via unary RPCexecute_subscription(): Execute GraphQL subscriptions via server streaming RPC
- Protocol Buffers: Complete proto definitions in
reinhardt-grpccrateGraphQLRequest: query, variables, operation_nameGraphQLResponse: data, errors, extensionsSubscriptionEvent: id, event_type, payload, timestamp
- Request/Response Conversion: Automatic conversion between gRPC and async-graphql types
- Error Handling: Full error information propagation (message, locations, path, extensions)
- Performance: Minimal overhead (5-21%, or 0.2-0.8 µs) compared to direct execution
- Network Communication: Full TCP/HTTP2 support via tonic
- Streaming: Efficient server-side streaming for real-time subscriptions
Dependency Injection (Optional - di feature)
#[graphql_handler]macro: Attribute macro for resolvers with automatic dependency injectionGraphQLContextExttrait: Extension trait for extracting DI context from GraphQL contextSchemaBuilderExttrait: Convenience methods for adding DI context to schema- Cache Control: Per-parameter cache control with
#[inject(cache = false)] - Type Safety: Full compile-time type checking for injected dependencies
- REST Consistency: Same DI patterns as REST handlers for unified developer experience
Installation
Add reinhardt to your Cargo.toml:
[]
= { = "0.1.0-alpha.1", = ["graphql"] }
# Or use a preset:
# reinhardt = { version = "0.1.0-alpha.1", features = ["standard"] } # Recommended
# reinhardt = { version = "0.1.0-alpha.1", features = ["full"] } # All features
Then import GraphQL features:
use ;
use ;
Note: GraphQL features are included in the standard and full feature presets.
Optional Features
# With dependency injection
= { = "0.1.0-alpha.1", = ["graphql", "di"] }
# With gRPC transport
= { = "0.1.0-alpha.1", = ["graphql", "grpc"] }
Examples
Basic GraphQL Usage
use ;
use ;
async
Dependency Injection
Enable the di feature to use dependency injection in GraphQL resolvers:
use ;
use ;
use InjectionContext;
use Arc;
// Define your resolvers
;
// Use #[graphql_handler] for DI
async
async
// Build schema with DI context
async
Cache Control
Control dependency caching per parameter:
async
GraphQL over gRPC Server
use ;
use GraphQLGrpcService;
use ;
use GraphQlServiceServer;
use Server;
async
GraphQL over gRPC Client
use ;
async
Running Examples
# Start gRPC server
# In another terminal, run client
Testing
# All tests
# Integration tests
# Subscription streaming tests
# E2E tests with real network
# Performance benchmarks
Performance
See PERFORMANCE.md for detailed benchmarks.
Summary:
- Direct GraphQL: ~3-4 µs per query
- gRPC GraphQL: ~4-5 µs per query
- Overhead: 5-21% (+0.2-0.8 µs) for gRPC serialization
- Both approaches are highly performant for real-world applications