|
| 1 | +# Design decisions vs. Go |
| 2 | + |
| 3 | +Rust differs enough from Go that a faithful port makes different choices in |
| 4 | +places. This lists where `oapi-codegen-rust` deviates from |
| 5 | +[`oapi-codegen`](https://github.com/oapi-codegen/oapi-codegen) and why. |
| 6 | + |
| 7 | +## Server: native async trait, axum only |
| 8 | + |
| 9 | +- **Go:** generates for many frameworks (chi, echo, gin, fiber, gorilla, iris, |
| 10 | + stdhttp) from a plain-method interface. |
| 11 | +- **Rust:** one `trait Api` using native async-fn-in-traits |
| 12 | + (`fn op(&self, ..) -> impl Future<Output = ..> + Send`), targeting axum 0.8. |
| 13 | + No `async-trait` dependency. |
| 14 | +- **Why:** stable Rust does async-in-traits natively; one well-supported |
| 15 | + framework keeps output idiomatic without a macro dependency. |
| 16 | +- There is a single server mode — a typed `trait Api`, comparable to Go's |
| 17 | + strict server. There is no unstructured handler variant. |
| 18 | + |
| 19 | +## Typed status-code response enums |
| 20 | + |
| 21 | +- **Go:** per-status response structs / context returns. |
| 22 | +- **Rust:** one `enum <Op>Response` per operation with a variant per declared |
| 23 | + status. The same enum implements `IntoResponse` on the server and is the |
| 24 | + client's success type, so a new status is a compile-enforced exhaustive match |
| 25 | + on both sides. |
| 26 | + |
| 27 | +## Token-based generation, not templates |
| 28 | + |
| 29 | +- **Go:** user-overridable `text/template`. |
| 30 | +- **Rust:** build a `TokenStream` with `quote!`, parse to `syn::File` (which |
| 31 | + guarantees syntactically valid Rust), and pretty-print with `prettyplease`. |
| 32 | + |
| 33 | +## Blocking `reqwest` client |
| 34 | + |
| 35 | +- Returns `Result<<Op>Response, ClientError>` with a single hand-written |
| 36 | + `ClientError` enum. Blocking by default, so no async runtime is forced on |
| 37 | + consumers. |
| 38 | + |
| 39 | +## Derive HTTP status semantics |
| 40 | + |
| 41 | +- Status codes come from the `http` / `axum` / `reqwest` `StatusCode` types |
| 42 | + rather than a hand-maintained reason/table mirror. |
| 43 | + |
| 44 | +## Vendor extensions |
| 45 | + |
| 46 | +- `x-rust-type`, `x-rust-name`, `x-rust-serde-skip`, plus `oapi-codegen` |
| 47 | + compatibility keys (`x-omitempty`, `x-order`, `x-deprecated-reason`, |
| 48 | + `x-enum-varnames` / `x-enumNames`). |
| 49 | +- `x-go-*` keys are ignored (accepted, no effect). See |
| 50 | + [extensions](extensions.md). |
| 51 | + |
| 52 | +## Combined output via submodules |
| 53 | + |
| 54 | +- Emitting server and client together puts shared component models at the crate |
| 55 | + root and the two targets in `server` / `client` submodules, resolving the |
| 56 | + same-named/different-shaped per-operation items. |
| 57 | + |
| 58 | +## OpenAPI 3.0 |
| 59 | + |
| 60 | +- The generator reads OpenAPI 3.0 documents (via the `openapiv3` crate). |
| 61 | + |
| 62 | +## Config compatibility |
| 63 | + |
| 64 | +- The YAML config mirrors `oapi-codegen`'s keys, and unknown keys are ignored, |
| 65 | + so an existing Go config can be reused as-is. See |
| 66 | + [configuration](configuration.md). |
0 commit comments