#rest #grpc #protobuf #axum #tonic

tonic-rest

Runtime types for REST + SSE endpoints generated from protobuf google.api.http annotations

6 releases

Uses new Rust 2024

0.1.5 Feb 15, 2026
0.1.4 Feb 14, 2026

#2399 in Network programming

Download history 16/week @ 2026-03-04 100/week @ 2026-03-11 67/week @ 2026-03-18 168/week @ 2026-03-25 256/week @ 2026-04-01 134/week @ 2026-04-08 186/week @ 2026-04-15 120/week @ 2026-04-22 98/week @ 2026-04-29 290/week @ 2026-05-06 247/week @ 2026-05-13 84/week @ 2026-05-20

744 downloads per month

MIT/Apache

85KB
1.5K SLoC

tonic-rest

Crates.io docs.rs License MSRV

Runtime types for REST + SSE endpoints generated from protobuf google.api.http annotations.

Part of the tonic-rest ecosystem — define your API once in proto files, get gRPC, REST, and OpenAPI 3.1.

This crate provides the shared types that generated Axum handlers reference at runtime. The companion crate tonic-rest-build generates the handler code at build time.

Key Features

  • Google error model — gRPC errors map to structured JSON responses following the Google API error model
  • SSE for server streaming — server-streaming RPCs are automatically exposed as Server-Sent Events endpoints
  • Request bridgingbuild_tonic_request forwards headers, extensions (e.g. auth info), and metadata from Axum to Tonic
  • Serde adapters — ready-made #[serde(with)] modules for Timestamp, Duration, FieldMask, and proto3 enums
  • Zero runtime reflection — all handler code is generated at build time by companion tonic-rest-build

Types

  • RestError — Converts tonic::Status to HTTP JSON error responses following the Google API error model
  • build_tonic_request — Bridges Axum HTTP requests to tonic::Request, forwarding headers and extensions (e.g., auth info)
  • sse_error_event — Formats gRPC errors as SSE events
  • grpc_to_http_status / grpc_code_name — Maps all 17 gRPC codes to HTTP status codes and canonical names

Error Response Format

RestError produces JSON responses following the Google API error model:

{
  "error": {
    "code": 404,
    "message": "user not found",
    "status": "NOT_FOUND"
  }
}

SSE error events use the same wrapped format with event: error type:

event: error
data: {"error":{"code":401,"status":"UNAUTHENTICATED","message":"token expired"}}

Serde Adapters

Behind the serde feature (enabled by default), provides #[serde(with)] adapters for prost well-known types:

Adapter Type Wire format
timestamp / opt_timestamp Timestamp / Option<Timestamp> RFC 3339 ("2025-01-15T09:30:00Z")
duration / opt_duration Duration / Option<Duration> Seconds with suffix ("300s")
field_mask / opt_field_mask FieldMask / Option<FieldMask> Comma-separated camelCase ("displayName,email")

And the define_enum_serde! macro for proto3 enum fields (which are i32 in prost):

tonic_rest::define_enum_serde!(user_role, crate::UserRole);
// With prefix stripping:
tonic_rest::define_enum_serde!(health_status, crate::HealthStatus, "HEALTH_STATUS_");

Feature Flags

Feature Default Description
serde on WKT serde adapters + define_enum_serde! macro (adds prost-types, chrono, serde deps)

Quick Start

[dependencies]
tonic-rest = "0.1"

[build-dependencies]
tonic-rest-build = "0.1"

For a complete end-to-end example, see auth-service-rs.

Companion Crates

Crate Purpose Cargo section
tonic-rest-core Shared descriptor types internal
tonic-rest (this) Runtime types [dependencies]
tonic-rest-build Build-time codegen [build-dependencies]
tonic-rest-openapi OpenAPI 3.1 generation CLI / CI

Compatibility

tonic-rest tonic axum prost-types MSRV
0.1.x 0.14 0.8 0.14 1.85

License

MIT OR Apache-2.0

Dependencies

~11–17MB
~242K SLoC