Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
grpc-graphql-gateway
A high-performance Rust gateway that bridges gRPC services to GraphQL with full Apollo Federation v2 support.
Transform your gRPC microservices into a unified GraphQL API with zero GraphQL code. This gateway dynamically generates GraphQL schemas from protobuf descriptors and routes requests to your gRPC backends via Tonic, providing a seamless bridge between gRPC and GraphQL ecosystems.
โจ Features
Core Capabilities
- ๐ Dynamic Schema Generation - Automatic GraphQL schema from protobuf descriptors
- โก Full Operation Support - Queries, Mutations, and Subscriptions
- ๐ WebSocket Subscriptions - Real-time data via GraphQL subscriptions (
graphql-wsprotocol) - ๐ค File Uploads - Multipart form data support for file uploads
- ๐ฏ Type Safety - Leverages Rust's type system for robust schema generation
Federation & Enterprise
- ๐ Apollo Federation v2 - Complete federation support with entity resolution
- ๐ Entity Resolution - Production-ready resolver with DataLoader batching
- ๐ซ No N+1 Queries - Built-in DataLoader prevents performance issues
- ๐ All Federation Directives -
@key,@external,@requires,@provides,@shareable - ๐ Batch Operations - Efficient entity resolution with automatic batching
Developer Experience
- ๐ ๏ธ Code Generation -
protoc-gen-graphql-templategenerates starter gateway code - ๐ง Middleware Support - Extensible middleware for auth, logging, and observability
- ๐ Rich Examples - Complete working examples for all features
- ๐งช Well Tested - Comprehensive test coverage
๐ Quick Start
Installation
[]
= "0.1"
= { = "1", = ["full"] }
= "0.12"
Basic Gateway
use ;
const DESCRIPTORS: & = include_bytes!;
async
Your gateway is now running!
- GraphQL HTTP:
http://localhost:8888/graphql - GraphQL WebSocket:
ws://localhost:8888/graphql/ws
Generate Descriptors
Add to your build.rs:
๐ Usage Examples
Queries, Mutations & Subscriptions
Annotate your proto file with GraphQL directives:
service UserService {
option (graphql.service) = {
host: "localhost:50051"
insecure: true
};
// Query
rpc GetUser(GetUserRequest) returns (User) {
option (graphql.schema) = {
type: QUERY
name: "user"
};
}
// Mutation
rpc CreateUser(CreateUserRequest) returns (User) {
option (graphql.schema) = {
type: MUTATION
name: "createUser"
request { name: "input" }
};
}
// Subscription (server streaming)
rpc WatchUser(WatchUserRequest) returns (stream User) {
option (graphql.schema) = {
type: SUBSCRIPTION
name: "userUpdates"
};
}
}
GraphQL operations:
# Query
query {
user(id: "123") {
id
name
email
}
}
# Mutation
mutation {
createUser(input: { name: "Alice", email: "alice@example.com" }) {
id
name
}
}
# Subscription
subscription {
userUpdates(id: "123") {
id
name
status
}
}
File Uploads
The gateway automatically supports GraphQL file uploads via multipart requests:
message UploadAvatarRequest {
string user_id = 1;
bytes avatar = 2; // Maps to Upload scalar in GraphQL
}
Field-Level Control
message User {
string id = 1 [(graphql.field) = { required: true }];
string email = 2 [(graphql.field) = { name: "emailAddress" }];
string internal_id = 3 [(graphql.field) = { omit: true }];
string password_hash = 4 [(graphql.field) = { omit: true }];
}
๐ Apollo Federation v2
Build federated GraphQL architectures with multiple subgraphs.
Defining Entities
message User {
option (graphql.entity) = {
keys: "id"
resolvable: true
};
string id = 1 [(graphql.field) = { required: true }];
string email = 2 [(graphql.field) = { shareable: true }];
string name = 3 [(graphql.field) = { shareable: true }];
}
message Product {
option (graphql.entity) = {
keys: "upc"
resolvable: true
};
string upc = 1 [(graphql.field) = { required: true }];
string name = 2 [(graphql.field) = { shareable: true }];
int32 price = 3 [(graphql.field) = { shareable: true }];
User created_by = 4 [(graphql.field) = {
name: "createdBy"
shareable: true
}];
}
Entity Resolution with DataLoader
The gateway includes production-ready entity resolution with automatic batching:
use ;
// Configure entity resolver with DataLoader batching
let resolver = builder
.register_entity_resolver
.build;
let gateway = builder
.with_descriptor_set_bytes
.enable_federation
.with_entity_resolver
.add_grpc_client
.serve
.await?;
Benefits:
- โ No N+1 Queries - DataLoader batches concurrent entity requests
- โ Automatic Batching - Multiple entities resolved in single operation
- โ Production Ready - Comprehensive error handling and logging
Extending Entities
message UserReviews {
option (graphql.entity) = {
extend: true
keys: "id"
};
string id = 1 [(graphql.field) = {
external: true
required: true
}];
repeated Review reviews = 2 [(graphql.field) = {
requires: "id"
}];
}
Federation Directives
| Directive | Purpose | Example |
|---|---|---|
@key |
Define entity key fields | keys: "id" |
@shareable |
Field resolvable from multiple subgraphs | shareable: true |
@external |
Field defined in another subgraph | external: true |
@requires |
Fields needed from other subgraphs | requires: "id email" |
@provides |
Fields this resolver provides | provides: "id name" |
Running with Apollo Router
# Start your federation subgraphs
# Compose the supergraph
# Run Apollo Router
Query the federated graph:
query {
product(upc: "123") {
upc
name
price
createdBy {
id
name
email # Resolved from User subgraph!
}
}
}
๐ง Advanced Features
Middleware
use ;
;
let gateway = builder
.add_middleware
.build?;
Custom Error Handling
let gateway = builder
.with_error_handler
.build?;
Response Plucking
Extract nested fields as top-level responses:
message ListUsersResponse {
repeated User users = 1;
int32 total = 2;
}
rpc ListUsers(ListUsersRequest) returns (ListUsersResponse) {
option (graphql.schema) = {
type: QUERY
name: "users"
response {
pluck: "users" // Returns [User] instead of ListUsersResponse
}
};
}
๐ Type Mapping
| Protobuf | GraphQL |
|---|---|
string |
String |
bool |
Boolean |
int32, uint32 |
Int |
int64, uint64 |
String (avoids precision loss) |
float, double |
Float |
bytes |
Upload (input) / String (output, base64) |
repeated T |
[T] |
message |
Object / InputObject |
enum |
Enum |
๐ ๏ธ Code Generation
Generate a starter gateway:
# Install the generator
# Generate gateway code
# Run the generated gateway
The generator creates:
- Complete gateway implementation
- Example queries/mutations/subscriptions
- Service configuration
- Ready-to-run code
๐ Examples
Greeter Example
Basic query, mutation, subscription, and file upload:
Open http://localhost:8888/graphql and try:
query { hello(name: "World") { message } }
mutation { updateGreeting(input: {name: "GraphQL", salutation: "Hey"}) { message } }
subscription { streamHello(name: "Stream") { message } }
Federation Example
Complete federated microservices with entity resolution:
Demonstrates:
- 3 federated subgraphs (User, Product, Review)
- Entity resolution with DataLoader batching
- Cross-subgraph queries
@shareablefields- Entity extensions
๐ฏ Best Practices
Federation
- Define Clear Boundaries - Each subgraph owns its entities
- Use @shareable Wisely - Mark fields resolved by multiple subgraphs
- Leverage DataLoader - Prevent N+1 queries with batch resolution
- Composite Keys - Use when entities need multiple identifiers
- Minimize @requires - Only specify truly required fields
Performance
- Enable Connection Pooling - Reuse gRPC connections
- Use Lazy Connections - Connect on first use
- Implement Caching - Cache frequently accessed entities
- Batch Operations - Use DataLoader for entity resolution
- Monitor Metrics - Track query performance and batch sizes
Security
- Validate Inputs - Use field-level validation
- Omit Sensitive Fields - Use
omit: truefor internal data - Implement Auth Middleware - Centralize authentication
- Rate Limiting - Protect against abuse
- TLS/SSL - Secure gRPC connections in production
๐งช Testing
# Run all tests
# Run with logging
RUST_LOG=debug
# Run specific test
๐ฆ Project Structure
grpc-graphql-gateway-rs/
โโโ src/
โ โโโ lib.rs # Public API
โ โโโ gateway.rs # Gateway implementation
โ โโโ schema.rs # Schema builder
โ โโโ federation.rs # Federation support
โ โโโ dataloader.rs # DataLoader for batching
โ โโโ grpc_client.rs # gRPC client management
โ โโโ middleware.rs # Middleware system
โ โโโ runtime.rs # HTTP/WebSocket server
โโโ proto/
โ โโโ graphql.proto # GraphQL annotations
โ โโโ *.proto # Your service definitions
โโโ examples/
โ โโโ greeter/ # Basic example
โ โโโ federation/ # Federation example
โโโ tests/ # Integration tests
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request. For major changes, please open an issue first to discuss what you would like to change.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Inspired by grpc-graphql-gateway (Go)
- Built with async-graphql
- Powered by tonic
- Federation based on Apollo Federation v2
๐ Links
Made with โค๏ธ by Protocol Lattice