@@ -23,7 +23,8 @@ package: apimodel # informational
2323output : models.rs # output path (overridden by -o)
2424generate :
2525 models : true
26- std-http-server : true # also emit an axum server interface
26+ std-http-server : true # emit an axum server interface, or…
27+ client : true # …a blocking reqwest client (server wins if both are set)
2728` ` `
2829
2930` import-mapping` maps a referenced spec file to the Rust module its schemas are
@@ -215,6 +216,62 @@ faithfully rather than emit subtly wrong code.
215216 the same operation (multipart needs its own extractor and cannot join the
216217 ` Content-Type` dispatch).
217218
219+ # # Client generation
220+
221+ Setting `generate.client` emits a blocking [`reqwest`] client alongside the
222+ models. Like the server, the output is typed-only and driven by the same
223+ internal representation, but it depends solely on `reqwest`, `serde`, and the
224+ generated models — never `axum` :
225+
226+ - a `struct Client` holding a `base_url` and a `reqwest::blocking::Client`, with
227+ ` Client::new(base_url)` (builds a default HTTP client) and
228+ ` Client::with_client(base_url, http)` (accepts a preconfigured client, e.g.
229+ with timeouts);
230+ - one method per operation returning `Result<<Op>Response, ClientError>`, whose
231+ arguments are the path parameters, a generated query-parameter struct, a
232+ generated header-parameter struct, a generated cookie-parameter struct, and the
233+ request body (each present only when the operation declares it);
234+ - a response `enum` per operation with one variant per documented status code
235+ (mirroring the server's shape but carrying `reqwest::StatusCode` for
236+ ` default` /range variants), plus a `ClientError` enum (`Http(reqwest::Error)`
237+ for transport/decoding failures, `UnexpectedStatus(reqwest::StatusCode)` for a
238+ status the operation does not declare).
239+
240+ Because the client cannot assume the server honoured the contract, response
241+ header fields are always `Option<T>` and parsed best-effort, even for headers the
242+ spec marks required.
243+
244+ A client crate needs `reqwest = { version = "0.12", features = ["blocking",
245+ " json" ] }`. The `json` feature is required when an operation sends a JSON request
246+ body and/or decodes a JSON response body.
247+
248+ **Supported**
249+
250+ - **Path, query, header, and cookie parameters** — the same scalar/array rules as
251+ the server. Query scalars and arrays (repeated keys, `style : form`,
252+ `explode : true`) are appended per field; headers and cookies are set from the
253+ generated input structs.
254+ - **Request bodies** — JSON (via `reqwest`'s `.json()`), form
255+ (`application/x-www-form-urlencoded`, via `.form()`), and `text/plain` (a raw
256+ string body with an explicit `Content-Type`).
257+ - **Responses** — fixed status codes, `default`, and ranges (`5XX`), decoding a
258+ JSON or `text/plain` body into the matching enum variant, along with declared
259+ response headers.
260+
261+ **Rejected / deferred** (an error, never mis-generated)
262+
263+ - A `multipart/form-data` request body (no multipart client encoder yet).
264+ - A request body that declares two or more content types (negotiated request
265+ bodies are server-only for now).
266+ - A response that declares two or more content types (negotiated responses are
267+ server-only for now).
268+ - A form (`application/x-www-form-urlencoded`) _response_ body.
269+
270+ Enabling both `std-http-server` and `client` emits the server (the client is a
271+ follow-up once multipart and negotiated bodies are supported on the client side).
272+ Path parameters are substituted verbatim without percent-encoding, which is safe
273+ for the scalar values the generator accepts.
274+
218275# # Coverage
219276
220277Every OpenAPI 3 schema element is deliberately catalogued — supported, ignored,
@@ -239,3 +296,4 @@ the unknown.
239296[`quote`] : https://crates.io/crates/quote
240297[`syn`] : https://crates.io/crates/syn
241298[`prettyplease`] : https://crates.io/crates/prettyplease
299+ [`reqwest`] : https://crates.io/crates/reqwest
0 commit comments