Skip to content

Commit c6e838a

Browse files
authored
test(cli): add status wrapper oapi-codegen e2e
Add an oapi-codegen-backed example and e2e coverage for generic status wrappers so generated specs and SDK types expose the real response payloads and statuses.
1 parent 1c2ce8e commit c6e838a

9 files changed

Lines changed: 469 additions & 0 deletions

File tree

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
# Status Wrapper OAPI Codegen Example
2+
3+
This example protects the integration path that caught the original
4+
`StatusResponse[T]` issue:
5+
6+
```text
7+
Fox handler -> fox-openapi CLI -> openapi.yaml -> oapi-codegen -> Go SDK types
8+
```
9+
10+
The handlers return a generic render wrapper only to control success status
11+
codes. The generated OpenAPI contract should expose the real wire responses:
12+
13+
- `POST /api/v1/sbx/sandboxes` returns `201` with `handler_SandboxResponse`.
14+
- `POST /api/v1/sbx/templates` returns `202` with `handler_TemplateResponse`.
15+
- No `StatusResponse[...]` wrapper schema should appear in the spec or generated
16+
SDK code.
17+
18+
Generate the OpenAPI document:
19+
20+
```bash
21+
go run github.com/fox-gonic/openapi/cmd/fox-openapi@latest \
22+
--workdir . \
23+
--entry github.com/fox-gonic/openapi/examples/status-wrapper-oapi-codegen/internal/handler.NewEngine \
24+
--out api/openapi.yaml \
25+
--title "Status Wrapper OAPI Codegen Example" \
26+
--version 1.0.0
27+
```
28+
29+
Generate downstream SDK code:
30+
31+
```bash
32+
go run github.com/oapi-codegen/oapi-codegen/v2/cmd/oapi-codegen@v2.4.1 \
33+
--config oapi-codegen.yaml \
34+
api/openapi.yaml
35+
```
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
components:
2+
responses:
3+
HTTPError:
4+
content:
5+
application/json:
6+
schema:
7+
$ref: "#/components/schemas/HTTPError"
8+
description: Error response
9+
schemas:
10+
HTTPError:
11+
additionalProperties: true
12+
properties:
13+
code:
14+
type: string
15+
error:
16+
type: string
17+
required:
18+
- code
19+
- error
20+
type: object
21+
handler_SandboxResponse:
22+
properties:
23+
client_id:
24+
description: ClientID identifies this platform to SDK clients.
25+
type: string
26+
sandbox_id:
27+
description: SandboxID is the sandbox instance ID.
28+
type: string
29+
template_id:
30+
description: TemplateID is the template used by the sandbox.
31+
type: string
32+
type: object
33+
handler_TemplateResponse:
34+
properties:
35+
build_id:
36+
description: BuildID is the latest template build ID.
37+
type: string
38+
name:
39+
description: Name is the template name.
40+
type: string
41+
template_id:
42+
description: TemplateID is the template ID.
43+
type: string
44+
type: object
45+
info:
46+
title: Status Wrapper OAPI Codegen Example
47+
version: 1.0.0
48+
openapi: 3.0.3
49+
paths:
50+
/api/v1/sbx/sandboxes:
51+
post:
52+
description: CreateSandbox creates a sandbox from a template.
53+
operationId: github_com_fox_gonic_openapi_examples_status_wrapper_oapi_codegen_internal_handler_CreateSandbox
54+
requestBody:
55+
content:
56+
application/json:
57+
schema:
58+
properties:
59+
template_id:
60+
description: TemplateID selects the template used to create the sandbox.
61+
type: string
62+
required:
63+
- template_id
64+
type: object
65+
required: true
66+
responses:
67+
"201":
68+
content:
69+
application/json:
70+
schema:
71+
$ref: "#/components/schemas/handler_SandboxResponse"
72+
description: Created
73+
default:
74+
$ref: "#/components/responses/HTTPError"
75+
summary: CreateSandbox creates a sandbox from a template.
76+
/api/v1/sbx/templates:
77+
post:
78+
description: CreateTemplate creates a template build request.
79+
operationId: github_com_fox_gonic_openapi_examples_status_wrapper_oapi_codegen_internal_handler_CreateTemplate
80+
requestBody:
81+
content:
82+
application/json:
83+
schema:
84+
properties:
85+
name:
86+
description: Name is the template name.
87+
type: string
88+
required:
89+
- name
90+
type: object
91+
required: true
92+
responses:
93+
"202":
94+
content:
95+
application/json:
96+
schema:
97+
$ref: "#/components/schemas/handler_TemplateResponse"
98+
description: Accepted
99+
default:
100+
$ref: "#/components/responses/HTTPError"
101+
summary: CreateTemplate creates a template build request.
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
entry: github.com/fox-gonic/openapi/examples/status-wrapper-oapi-codegen/internal/handler.NewEngine
2+
out: api/openapi.yaml
3+
format: yaml
4+
sources:
5+
- ./internal/handler
6+
info:
7+
title: Status Wrapper OAPI Codegen Example
8+
version: 1.0.0
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
module github.com/fox-gonic/openapi/examples/status-wrapper-oapi-codegen
2+
3+
go 1.25.0
4+
5+
require github.com/fox-gonic/fox v0.0.11
6+
7+
require (
8+
github.com/bytedance/gopkg v0.1.3 // indirect
9+
github.com/bytedance/sonic v1.15.0 // indirect
10+
github.com/bytedance/sonic/loader v0.5.0 // indirect
11+
github.com/cloudwego/base64x v0.1.6 // indirect
12+
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
13+
github.com/gin-contrib/cors v1.7.7 // indirect
14+
github.com/gin-contrib/sse v1.1.0 // indirect
15+
github.com/gin-gonic/gin v1.12.0 // indirect
16+
github.com/go-playground/locales v0.14.1 // indirect
17+
github.com/go-playground/universal-translator v0.18.1 // indirect
18+
github.com/go-playground/validator/v10 v10.30.1 // indirect
19+
github.com/goccy/go-json v0.10.6 // indirect
20+
github.com/goccy/go-yaml v1.19.2 // indirect
21+
github.com/json-iterator/go v1.1.12 // indirect
22+
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
23+
github.com/leodido/go-urn v1.4.0 // indirect
24+
github.com/mattn/go-colorable v0.1.14 // indirect
25+
github.com/mattn/go-isatty v0.0.20 // indirect
26+
github.com/mitchellh/mapstructure v1.5.0 // indirect
27+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
28+
github.com/modern-go/reflect2 v1.0.2 // indirect
29+
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
30+
github.com/quic-go/qpack v0.6.0 // indirect
31+
github.com/quic-go/quic-go v0.59.0 // indirect
32+
github.com/rs/zerolog v1.35.1 // indirect
33+
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
34+
github.com/ugorji/go/codec v1.3.1 // indirect
35+
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
36+
golang.org/x/arch v0.25.0 // indirect
37+
golang.org/x/crypto v0.50.0 // indirect
38+
golang.org/x/net v0.53.0 // indirect
39+
golang.org/x/sys v0.43.0 // indirect
40+
golang.org/x/text v0.36.0 // indirect
41+
google.golang.org/protobuf v1.36.11 // indirect
42+
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
43+
)
44+
45+
replace github.com/fox-gonic/openapi => ../..
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
2+
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
3+
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
4+
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
5+
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
6+
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
7+
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
8+
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
9+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
10+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
11+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
12+
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
13+
github.com/fox-gonic/fox v0.0.11 h1:Rfth9YjAP9IHNp7u2Mt1SOKl44Tp0wXm7MPyhWp4buo=
14+
github.com/fox-gonic/fox v0.0.11/go.mod h1:JP6B9M4Apg/p35XwqdPgxOWTZtIuXiNyXHr5KBgSY9I=
15+
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
16+
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
17+
github.com/gin-contrib/cors v1.7.7 h1:Oh9joP463x7Mw72vhvJ61YQm8ODh9b04YR7vsOErD0Q=
18+
github.com/gin-contrib/cors v1.7.7/go.mod h1:K5tW0RkzJtWSiOdikXloy8VEZlgdVNpHNw8FpjUPNrE=
19+
github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w=
20+
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
21+
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
22+
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
23+
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
24+
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
25+
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
26+
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
27+
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
28+
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
29+
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
30+
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
31+
github.com/goccy/go-json v0.10.6 h1:p8HrPJzOakx/mn/bQtjgNjdTcN+/S6FcG2CTtQOrHVU=
32+
github.com/goccy/go-json v0.10.6/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
33+
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
34+
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
35+
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
36+
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
37+
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
38+
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
39+
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
40+
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
41+
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
42+
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
43+
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
44+
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
45+
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
46+
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
47+
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
48+
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
49+
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
50+
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
51+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
52+
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
53+
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
54+
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
55+
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
56+
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
57+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
58+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
59+
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
60+
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
61+
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
62+
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
63+
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
64+
github.com/rs/zerolog v1.35.1 h1:m7xQeoiLIiV0BCEY4Hs+j2NG4Gp2o2KPKmhnnLiazKI=
65+
github.com/rs/zerolog v1.35.1/go.mod h1:EjML9kdfa/RMA7h/6z6pYmq1ykOuA8/mjWaEvGI+jcw=
66+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
67+
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
68+
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
69+
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
70+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
71+
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
72+
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
73+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
74+
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
75+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
76+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
77+
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
78+
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
79+
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
80+
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
81+
go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE=
82+
go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
83+
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
84+
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
85+
golang.org/x/arch v0.25.0 h1:qnk6Ksugpi5Bz32947rkUgDt9/s5qvqDPl/gBKdMJLE=
86+
golang.org/x/arch v0.25.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
87+
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
88+
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
89+
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
90+
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
91+
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
92+
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
93+
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
94+
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
95+
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
96+
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
97+
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
98+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
99+
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
100+
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
101+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
102+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
103+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// Package apis is the output package for oapi-codegen in this example.
2+
package apis
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package handler
2+
3+
import (
4+
"encoding/json"
5+
"net/http"
6+
7+
"github.com/fox-gonic/fox"
8+
)
9+
10+
type StatusResponse[T any] struct {
11+
status int
12+
data T
13+
}
14+
15+
func statusResponse[T any](status int, data T) StatusResponse[T] {
16+
return StatusResponse[T]{status: status, data: data}
17+
}
18+
19+
func (r StatusResponse[T]) Render(w http.ResponseWriter) error {
20+
r.WriteContentType(w)
21+
w.WriteHeader(r.status)
22+
return json.NewEncoder(w).Encode(r.data)
23+
}
24+
25+
func (r StatusResponse[T]) WriteContentType(w http.ResponseWriter) {
26+
w.Header().Set("Content-Type", "application/json; charset=utf-8")
27+
}
28+
29+
type CreateSandboxRequest struct {
30+
// TemplateID selects the template used to create the sandbox.
31+
TemplateID string `json:"template_id" binding:"required"`
32+
}
33+
34+
type SandboxResponse struct {
35+
// SandboxID is the sandbox instance ID.
36+
SandboxID string `json:"sandbox_id"`
37+
// TemplateID is the template used by the sandbox.
38+
TemplateID string `json:"template_id"`
39+
// ClientID identifies this platform to SDK clients.
40+
ClientID string `json:"client_id"`
41+
}
42+
43+
type CreateTemplateRequest struct {
44+
// Name is the template name.
45+
Name string `json:"name" binding:"required"`
46+
}
47+
48+
type TemplateResponse struct {
49+
// TemplateID is the template ID.
50+
TemplateID string `json:"template_id"`
51+
// BuildID is the latest template build ID.
52+
BuildID string `json:"build_id"`
53+
// Name is the template name.
54+
Name string `json:"name"`
55+
}
56+
57+
func NewEngine() *fox.Engine {
58+
engine := fox.New()
59+
engine.POST("/api/v1/sbx/sandboxes", CreateSandbox)
60+
engine.POST("/api/v1/sbx/templates", CreateTemplate)
61+
return engine
62+
}
63+
64+
// CreateSandbox creates a sandbox from a template.
65+
func CreateSandbox(_ *fox.Context, req CreateSandboxRequest) (StatusResponse[SandboxResponse], error) {
66+
return statusResponse(http.StatusCreated, SandboxResponse{
67+
SandboxID: "sbx_123",
68+
TemplateID: req.TemplateID,
69+
ClientID: "client_123",
70+
}), nil
71+
}
72+
73+
// CreateTemplate creates a template build request.
74+
func CreateTemplate(_ *fox.Context, req CreateTemplateRequest) (StatusResponse[TemplateResponse], error) {
75+
return statusResponse(http.StatusAccepted, TemplateResponse{
76+
TemplateID: "tpl_123",
77+
BuildID: "build_123",
78+
Name: req.Name,
79+
}), nil
80+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package: apis
2+
output: internal/apis/sandbox.gen.go
3+
generate:
4+
models: true
5+
client: true
6+
output-options:
7+
name-normalizer: ToCamelCaseWithInitialisms

0 commit comments

Comments
 (0)