Skip to content

Commit 0479d1d

Browse files
authored
Generate client with response (#80)
1 parent 743cf20 commit 0479d1d

45 files changed

Lines changed: 1784 additions & 9 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ on the real value-add for your organization.
2323

2424
### Client Generation
2525
- **HTTP client generation** - Generate type-safe HTTP clients with customizable timeout and request editors
26+
- **Envelope `WithResponse` clients** - Opt-in `<Op>WithResponse` siblings that return a typed envelope with per-status bodies, typed headers, and the raw `*http.Response` - useful for operations that legitimately return multiple 2xx statuses or need typed access to response headers
2627
- **Custom client types** - Wrap generated clients with your own types for additional functionality
2728
- **Error mapping** - Map response types to implement the `error` interface automatically
2829

configuration-schema.json

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,11 @@
100100
"properties": {
101101
"client": {
102102
"type": "boolean",
103-
"description": "Client specifies whether to generate a client. Defaults to false."
103+
"description": "Generate the classic client: one method per operation returning the picked 2xx body directly (e.g. UploadDocument(...) (*DocumentStored, error)). Use this when callers only need the response body and the operation has a single documented success status; headers and non-picked 2xx bodies are not exposed. Combine with client-with-response when an operation has multiple 2xx statuses or callers need typed headers - both flags can be true and the generated ClientInterface will list both styles. Defaults to false."
104+
},
105+
"client-with-response": {
106+
"type": "boolean",
107+
"description": "Generate <Op>WithResponse sibling functions that return a typed envelope: one JSON<status> field per documented response, one Headers<status> typed struct per status that declares headers, plus HTTPResponse *http.Response for raw access. Use when an operation has multiple 2xx statuses with different bodies (e.g. 201 sync + 202 queued) or when callers need typed access to headers like Location or Retry-After. Additive to client: when both are true the combined ClientInterface lists both styles. Defaults to false."
104108
},
105109
"models": {
106110
"type": "boolean",

docs/configuration.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,9 @@ output:
140140
#### `generate.client`
141141
**Type:** `boolean` | **Default:** `false`
142142

143-
Generate HTTP client code for calling the API.
143+
Generate the classic HTTP client: one method per operation that returns the picked 2xx body type directly (e.g. `func (c *Client) UploadDocument(...) (*DocumentStored, error)`).
144+
145+
Use this when callers only need the response body and the operation has a single documented success status. Headers and non-picked 2xx bodies are not exposed by this style; for those, use [`generate.client-with-response`](#generateclient-with-response) instead, or both together.
144146

145147
```yaml
146148
generate:
@@ -149,6 +151,32 @@ generate:
149151

150152
See [examples/client/example1/cfg.yaml](https://github.com/doordash-oss/oapi-codegen-dd/blob/main/examples/client/example1/cfg.yaml){:target="_blank"} for a complete example.
151153

154+
#### `generate.client-with-response`
155+
**Type:** `boolean` | **Default:** `false`
156+
157+
Generate `<Op>WithResponse` sibling functions that return a typed envelope: one `JSON<status>` (or `Text<status>` / `HTML<status>` / etc.) field per documented response, one `Headers<status>` typed struct per status that declares headers, plus `HTTPResponse *http.Response` for raw access (undocumented headers, raw body bytes, status string, etc.).
158+
159+
Use this when an operation has multiple 2xx statuses with different bodies (e.g. 201 sync + 202 queued), or when callers need typed access to response headers like `Location` or `Retry-After`.
160+
161+
Additive to [`generate.client`](#generateclient). When both flags are true, the generated `ClientInterface` lists every classic method alongside its `WithResponse` sibling so a single mock or test double covers both shapes.
162+
163+
```yaml
164+
generate:
165+
client: true
166+
client-with-response: true
167+
```
168+
169+
The four valid combinations:
170+
171+
| `client` | `client-with-response` | Output |
172+
|----------|------------------------|--------|
173+
| `false` | `false` | No client (types/server only) |
174+
| `true` | `false` | Classic client only |
175+
| `false` | `true` | Envelope client only |
176+
| `true` | `true` | Both styles, combined into one `ClientInterface` |
177+
178+
See [examples/responses/multiple/client-with-response/cfg.yaml](https://github.com/doordash-oss/oapi-codegen-dd/blob/main/examples/responses/multiple/client-with-response/cfg.yaml){:target="_blank"} for envelope-only and [examples/responses/multiple/client-combined/cfg.yaml](https://github.com/doordash-oss/oapi-codegen-dd/blob/main/examples/responses/multiple/client-combined/cfg.yaml){:target="_blank"} for the combined case.
179+
152180
#### `generate.omit-description`
153181
**Type:** `boolean` | **Default:** `false`
154182

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
openapi: 3.0.3
2+
info:
3+
title: Document Upload API
4+
version: 1.0.0
5+
6+
paths:
7+
/documents:
8+
post:
9+
operationId: uploadDocument
10+
summary: Upload a document
11+
requestBody:
12+
required: true
13+
content:
14+
application/json:
15+
schema:
16+
$ref: '#/components/schemas/UploadRequest'
17+
responses:
18+
'201':
19+
description: Document stored synchronously
20+
headers:
21+
Location:
22+
schema:
23+
type: string
24+
format: uri
25+
X-Request-Id:
26+
schema:
27+
type: string
28+
content:
29+
application/json:
30+
schema:
31+
$ref: '#/components/schemas/DocumentStored'
32+
'202':
33+
description: Document queued for async processing
34+
headers:
35+
X-Request-Id:
36+
schema:
37+
type: string
38+
Retry-After:
39+
schema:
40+
type: integer
41+
content:
42+
application/json:
43+
schema:
44+
$ref: '#/components/schemas/DocumentQueued'
45+
'422':
46+
description: Invalid document
47+
content:
48+
application/json:
49+
schema:
50+
$ref: '#/components/schemas/ValidationError'
51+
'503':
52+
description: Service unavailable. Plain-text human-readable reason.
53+
content:
54+
text/plain:
55+
schema:
56+
type: string
57+
58+
components:
59+
schemas:
60+
UploadRequest:
61+
type: object
62+
required: [filename, content]
63+
properties:
64+
filename:
65+
type: string
66+
content:
67+
type: string
68+
format: byte
69+
DocumentStored:
70+
type: object
71+
required: [id, url]
72+
properties:
73+
id:
74+
type: string
75+
format: uuid
76+
url:
77+
type: string
78+
format: uri
79+
DocumentQueued:
80+
type: object
81+
required: [job_id, estimated_completion_seconds]
82+
properties:
83+
job_id:
84+
type: string
85+
format: uuid
86+
estimated_completion_seconds:
87+
type: integer
88+
ValidationError:
89+
type: object
90+
required: [code, message]
91+
properties:
92+
code:
93+
type: string
94+
message:
95+
type: string
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# yaml-language-server: $schema=../../../configuration-schema.json
2+
package: gen
3+
output:
4+
use-single-file: false
5+
generate:
6+
client: true
7+
client-with-response: true
8+
omit-description: true

examples/responses/multiple/client-combined/gen/client.go

Lines changed: 101 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/responses/multiple/client-combined/gen/client_options.go

Lines changed: 51 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)