tonic-rest-openapi
OpenAPI 3.1 spec generation and patching from protobuf descriptors for Tonic gRPC services.
Reads compiled protobuf FileDescriptorSet bytes and a gnostic-generated OpenAPI YAML spec,
then applies a configurable pipeline of transforms to produce a clean OpenAPI 3.1 spec that
matches the runtime REST behavior.
Pipeline
The 12-phase transform pipeline:
| Phase | Transform |
|---|---|
| 1 | OpenAPI 3.0 → 3.1 (version + nullable conversion) |
| 2 | SSE streaming annotations |
| 3 | Response fixes (empty→204, redirects, error schemas) |
| 4 | Enum value rewrites (strip UNSPECIFIED, normalize values) |
| 5 | Unimplemented operation markers (501) |
| 6 | Security (Bearer JWT, public endpoint overrides) |
| 7 | Cleanup (tags, empty bodies, unused schemas) |
| 8 | UUID wrapper flattening (inline string/uuid) |
| 9 | Validation constraint injection (from proto rules) |
| 10 | Path parameter enrichment |
| 11 | Request body inlining + orphan removal |
| 12 | CRLF → LF normalization |
Each phase can be individually enabled/disabled via PatchConfig or ProjectConfig.
Usage
As a Library
use ;
// From a config file
let project = load?;
let metadata = discover?;
let config = new.with_project_config;
let patched_yaml = patch?;
Or configure programmatically:
let config = new
.unimplemented_methods
.public_methods
.bearer_description
.error_schema_ref;
let patched_yaml = patch?;
As a CLI
# Full pipeline: lint → generate → patch
# Standalone patch
# Discover proto metadata
Enable the cli feature for the binary:
[]
= { = "0.1", = ["cli"] }
Feature Flags
| Feature | Default | Description |
|---|---|---|
cli |
off | CLI binary with generate, patch, discover, inject-version subcommands (adds clap, toml, anyhow) |
Project Config File
# api/openapi/config.yaml
error_schema_ref: "#/components/schemas/ErrorResponse"
unimplemented_methods:
- SetupMfa
public_methods:
- Login
- SignUp
plain_text_endpoints:
- path: /health/live
example: "OK"
metrics_path: /metrics
readiness_path: /health/ready
transforms:
upgrade_to_3_1: true
annotate_sse: true
inject_validation: true
add_security: true
For a complete end-to-end example with proto files, build.rs, REST handlers, and OpenAPI generation,
see auth-service-rs.
Companion Crates
| Crate | Purpose | Cargo section |
|---|---|---|
| tonic-rest | Runtime types | [dependencies] |
| tonic-rest-build | Build-time codegen | [build-dependencies] |
| tonic-rest-openapi (this) | OpenAPI 3.1 generation | CLI / CI |
Note:
tonic-rest-openapidepends ontonic-rest-build(as a regular[dependency], not a[build-dependency]) for shared proto descriptor types. This means addingtonic-rest-openapito your project will pull intonic-rest-buildas a transitive runtime dependency. This is intentional — both crates share the same customprost::Messagetypes for parsinggoogle.api.httpannotations. If you only need OpenAPI generation in CI (not in your application binary), consider using the CLI binary or a separate workspace crate.
Dependencies
This crate uses serde_yaml_ng for YAML parsing
and serialization. serde_yaml_ng is a maintained fork of the archived serde_yaml crate.
While it is the best available option today, be aware that its ecosystem adoption is narrower
than serde_json. If a more widely-adopted YAML serde library emerges in the future,
migration may be warranted.
Compatibility
| tonic-rest-openapi | tonic-rest-build | prost | MSRV |
|---|---|---|---|
| 0.1.x | 0.1 | 0.14 | 1.82 |