Your proto is the plan.
Generate a typed GraphQL schema directly from annotated protobuf descriptors. Keep your service definitions in one place.
From proto to GraphQLYour gRPC stack. A GraphQL experience.
Turn your protobuf definitions into a unified GraphQL API.
Queries, mutations, and real-time updates.
Without the handwritten resolvers.
cargo add grpc_graphql_gateway◇ Open source. Rust powered. MIT licensed.
users.protoproducts.protoorders.protoPOWERED BY RUSTONE ENDPOINTYour services already do the hard work.
Give them a flexible API that’s a pleasure to use.
Generate a typed GraphQL schema directly from annotated protobuf descriptors. Keep your service definitions in one place.
From proto to GraphQLBring your services into an Apollo Federation v2 supergraph. Resolve entities efficiently with built-in DataLoader batching.
Connect your supergraphMap server streams to subscriptions, or keep results fresh with live queries. Real-time experiences, powered by your gRPC services.
Keep your clients in syncA small annotation. A whole new interface.
Explore the connection, one operation at a time.
Annotate a protobuf method and let the gateway generate the schema. Your clients choose the fields. Your gRPC service does the work.
Read the guide// Add to your annotated UserServicerpc GetUser(GetUserRequest) returns (User) { option (graphql.schema) = { type: QUERY name: "user" };}query GetUser { user(id: "123") { id name email }}{
"data": {
"user": {
"id": "123",
"name": "Alice",
"email": "alice@example.com"
}
}
}Illustrative response from the annotated GetUser service.
Expose a write operation as a GraphQL mutation. Wrap the request fields in a typed input and route the call to your existing gRPC method.
Read the guiderpc CreateUser(CreateUserRequest) returns (User) { option (graphql.schema) = { type: MUTATION name: "createUser" request { name: "input" } };}mutation CreateUser { createUser(input: { name: "Alice" email: "alice@example.com" }) { id name }}{
"data": {
"createUser": {
"id": "123",
"name": "Alice"
}
}
}Illustrative response. This demo does not create a user.
Turn a server-streaming RPC into a GraphQL subscription. Deliver ongoing updates over WebSocket using the graphql-transport-ws protocol.
Read the guiderpc WatchUser(WatchUserRequest) returns (stream User) { option (graphql.schema) = { type: SUBSCRIPTION name: "userUpdates" };}subscription WatchUser { userUpdates(id: "123") { id name status }}{
"data": {
"userUpdates": {
"id": "123",
"name": "Alice",
"status": "ONLINE"
}
}
}Illustrative event. Connect your client to /graphql/ws to stream.
Define entity keys in protobuf and enable Federation v2. Compose your gRPC services with other subgraphs through Apollo Router.
Read the guidemessage User { option (graphql.entity) = { keys: "id" resolvable: true }; string id = 1 [(graphql.field) = { required: true }]; string name = 2; string email = 3;}type User @key(fields: "id") { id: ID! name: String email: String}{
"data": {
"_service": {
"sdl": "type User @key(fields: \"id\") { id: ID! name: String email: String }"
}
}
}Illustrative _service response after federation is enabled.
Real examples, from the gateway documentation.Also supports file uploads and @defer
Rust at the core. Practical controls at the edges.
The building blocks your production stack needs.
Response caching, persisted queries, and request collapsing. Do less work for every request.
Query depth and complexity limits, authentication, and circuit breakers. Put the right controls in place.
Prometheus metrics, OpenTelemetry tracing, and health checks. From GraphQL request to gRPC response.
Deploy with Helm, combine descriptor sets, or connect REST APIs. Build around the services you have.
Your first gateway starts here.
Bring a gRPC service. We’ll make the connection.
A small addition to your Rust project.
Annotate your proto and compile with protoc.
Connect your backend. Meet your GraphQL API.
use grpc_graphql_gateway::{Gateway, GrpcClient}; #[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { Gateway::builder() .with_descriptor_set_file("descriptor.bin")? .add_grpc_client( "greeter.Greeter", GrpcClient::builder("http://localhost:50051") .connect_lazy()?, ) .build()? .serve("0.0.0.0:8888") .await?; Ok(())}[dependencies]grpc_graphql_gateway = "1.2.5"tokio = { version = "1", features = ["full"] }syntax = "proto3";package greeter; import "graphql.proto"; service Greeter { rpc SayHello(HelloRequest) returns (HelloReply) { option (graphql.schema) = { type: QUERY name: "sayHello" }; }} message HelloRequest { string name = 1; }message HelloReply { string message = 1; }localhost:8888/graphqlRequires a running Greeter gRPC backend and descriptor.bin.
Start with the descriptor guide to generate it.
Build something useful. Make your services go further.
Help shape what comes next for the gateway.