Skip to content

Commit eb2302b

Browse files
kesonanCopilot
andauthored
fix(swagger): add example field to path/form/header parameters (#5497)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 04ed637 commit eb2302b

File tree

4 files changed

+154
-0
lines changed

4 files changed

+154
-0
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
syntax = "v1"
2+
3+
info (
4+
title: "Issue 5496 Reproduce"
5+
version: "v1"
6+
host: "localhost"
7+
)
8+
9+
// Reproduces issue #5496:
10+
// The `example` tag option in `path` and `form` tags does not appear in generated swagger JSON.
11+
type (
12+
Request {
13+
// path param with example — should appear as example in swagger
14+
Name string `path:"name,options=you|me,example=nihao"`
15+
// form param with example and range — should appear as example in swagger
16+
Age int `form:"age,optional,range=[1:200],example=18"`
17+
}
18+
Response {
19+
Name string `json:"name,example=nihao"`
20+
Age int `json:"age,example=18"`
21+
}
22+
)
23+
24+
@server (
25+
tags: "issue5496"
26+
summary: "Issue 5496 - example field missing for path/form params"
27+
)
28+
service issue5496 {
29+
@doc (
30+
description: "Demonstrate that example is missing in path/form swagger params"
31+
)
32+
@handler getUser
33+
get /user/:name (Request) returns (Response)
34+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
{
2+
"consumes": [
3+
"application/json"
4+
],
5+
"produces": [
6+
"application/json"
7+
],
8+
"schemes": [
9+
"https"
10+
],
11+
"swagger": "2.0",
12+
"info": {
13+
"title": "Issue 5496 Reproduce",
14+
"version": "v1"
15+
},
16+
"host": "localhost",
17+
"basePath": "/",
18+
"paths": {
19+
"/user/{name}": {
20+
"get": {
21+
"description": "Demonstrate that example is missing in path/form swagger params",
22+
"produces": [
23+
"application/json"
24+
],
25+
"schemes": [
26+
"https"
27+
],
28+
"tags": [
29+
"issue5496"
30+
],
31+
"summary": "getUser",
32+
"operationId": "getUser",
33+
"parameters": [
34+
{
35+
"enum": [
36+
"you",
37+
"me"
38+
],
39+
"type": "string",
40+
"example": "nihao",
41+
"name": "name",
42+
"in": "path",
43+
"required": true
44+
},
45+
{
46+
"maximum": 200,
47+
"minimum": 1,
48+
"type": "integer",
49+
"example": 18,
50+
"name": "age",
51+
"in": "query",
52+
"allowEmptyValue": true
53+
}
54+
],
55+
"responses": {
56+
"200": {
57+
"description": "",
58+
"schema": {
59+
"type": "object",
60+
"properties": {
61+
"age": {
62+
"type": "integer",
63+
"example": 18
64+
},
65+
"name": {
66+
"type": "string",
67+
"example": "nihao"
68+
}
69+
}
70+
}
71+
}
72+
}
73+
}
74+
}
75+
},
76+
"x-date": "2026-03-19 22:52:34",
77+
"x-description": "This is a goctl generated swagger file.",
78+
"x-github": "https://github.com/zeromicro/go-zero",
79+
"x-go-zero-doc": "https://go-zero.dev/",
80+
"x-goctl-version": "1.10.0"
81+
}

tools/goctl/api/swagger/parameter.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
7272
SimpleSchema: spec.SimpleSchema{
7373
Type: sampleTypeFromGoType(ctx, member.Type),
7474
Default: defValueFromOptions(ctx, headerTag.Options, member.Type),
75+
Example: exampleValueFromOptions(ctx, headerTag.Options, member.Type),
7576
Items: sampleItemsFromGoType(ctx, member.Type),
7677
},
7778
ParamProps: spec.ParamProps{
@@ -96,6 +97,7 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
9697
SimpleSchema: spec.SimpleSchema{
9798
Type: sampleTypeFromGoType(ctx, member.Type),
9899
Default: defValueFromOptions(ctx, pathParameterTag.Options, member.Type),
100+
Example: exampleValueFromOptions(ctx, pathParameterTag.Options, member.Type),
99101
Items: sampleItemsFromGoType(ctx, member.Type),
100102
},
101103
ParamProps: spec.ParamProps{
@@ -121,6 +123,7 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
121123
SimpleSchema: spec.SimpleSchema{
122124
Type: sampleTypeFromGoType(ctx, member.Type),
123125
Default: defValueFromOptions(ctx, formTag.Options, member.Type),
126+
Example: exampleValueFromOptions(ctx, formTag.Options, member.Type),
124127
Items: sampleItemsFromGoType(ctx, member.Type),
125128
},
126129
ParamProps: spec.ParamProps{
@@ -143,6 +146,7 @@ func parametersFromType(ctx Context, method string, tp apiSpec.Type) []spec.Para
143146
SimpleSchema: spec.SimpleSchema{
144147
Type: sampleTypeFromGoType(ctx, member.Type),
145148
Default: defValueFromOptions(ctx, formTag.Options, member.Type),
149+
Example: exampleValueFromOptions(ctx, formTag.Options, member.Type),
146150
Items: sampleItemsFromGoType(ctx, member.Type),
147151
},
148152
ParamProps: spec.ParamProps{

tools/goctl/api/swagger/parameter_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,41 @@ func TestParametersFromType_EdgeCases(t *testing.T) {
8383
assert.Empty(t, params)
8484
}
8585

86+
// TestParametersFromType_ExampleField reproduces issue #5496:
87+
// example= in path/form tags was not emitted in the generated swagger JSON.
88+
func TestParametersFromType_ExampleField(t *testing.T) {
89+
ctx := testingContext(t)
90+
91+
testStruct := apiSpec.DefineStruct{
92+
RawName: "Request",
93+
Members: []apiSpec.Member{
94+
{
95+
Name: "Name",
96+
Type: apiSpec.PrimitiveType{RawName: "string"},
97+
Tag: `path:"name,options=you|me,example=nihao"`,
98+
},
99+
{
100+
Name: "Age",
101+
Type: apiSpec.PrimitiveType{RawName: "int"},
102+
Tag: `form:"age,optional,range=[1:200],example=18"`,
103+
},
104+
},
105+
}
106+
107+
params := parametersFromType(ctx, http.MethodGet, testStruct)
108+
assert.Len(t, params, 2)
109+
110+
// path param should have example
111+
pathParam := params[0]
112+
assert.Equal(t, paramsInPath, pathParam.In)
113+
assert.Equal(t, "nihao", pathParam.SimpleSchema.Example, "path param example should be set")
114+
115+
// form/query param should have example
116+
queryParam := params[1]
117+
assert.Equal(t, paramsInQuery, queryParam.In)
118+
assert.EqualValues(t, int64(18), queryParam.SimpleSchema.Example, "form param example should be set")
119+
}
120+
86121
func createTestStruct(name string, hasJson bool) apiSpec.DefineStruct {
87122
tag := `form:"username"`
88123
if hasJson {

0 commit comments

Comments
 (0)