Skip to content

Commit 76457ee

Browse files
committed
feat: request
1 parent 814785d commit 76457ee

File tree

9 files changed

+183
-113
lines changed

9 files changed

+183
-113
lines changed

examples/common/response.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package common
2+
3+
type Response struct {
4+
Code int
5+
Msg string
6+
Data interface{}
7+
Common float64
8+
Common2 string
9+
}

examples/docs/apis-greeter.md

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,41 +4,60 @@ greeter分组说明
44

55
## Apis
66

7-
### 测试greeter
7+
### @api 测试greeter
88

99
```text
1010
GET /greeter
1111
```
1212

13+
**Request**:
14+
parameters|type|required|validate|example|description
15+
--|--|--|--|--|--
16+
**id**|*header,query*|true||12357|this id
17+
**tid**|*param*|true|required|123|
18+
**token**|*header*|false||"example"|
1319
**Response**:
1420

1521
```json
1622
// StatusCode: 200
1723

1824
// 输出对象 dd
19-
{ //object(main.Response), 通用返回结果
20-
"code": 0, //int, 返回状态码
25+
{ //object(common.Response)
26+
"Code": 123, //int
27+
"Common": 1.23, //float64
28+
"Common2": "example", //string
29+
"Data": null, //any
30+
"Msg": "example", //string
2131
"data": { //object(main.TestData)
2232
"MyIntArray": [ //array[int]
23-
0
33+
123
2434
],
2535
"MyTestData2Array": [ //array[main.TestData2]
2636
{ //object(main.TestData2)
27-
"MyAge2": 0, //int
37+
"MyAge2": 123, //int
2838
"MyTitle2": "example" //string, 标题2
2939
}
3040
],
3141
"data2": { //object(main.TestData2)
32-
"MyAge2": 0, //int
42+
"MyAge2": 123, //int
3343
"MyTitle2": "example" //string, 标题2
3444
},
3545
"my_title": "example" //string, 标题
36-
},
37-
"msg": "返回消息" //string, 返回文本消息
46+
}
47+
}
48+
```
49+
50+
```json
51+
// StatusCode: 500
52+
53+
// 出错了
54+
{ //object(main.Response), 通用返回结果
55+
"code": 10010, //int, 返回状态码
56+
"msg": "异常", //string, 返回文本消息
3857
}
3958
```
4059

41-
### 测试greeter2
60+
### @api 测试greeter2
4261

4362
```text
4463
GET /greeter2
@@ -52,16 +71,16 @@ GET /greeter2
5271
// 输出对象 dd
5372
{ //object(main.TestData)
5473
"MyIntArray": [ //array[int]
55-
0
74+
123
5675
],
5776
"MyTestData2Array": [ //array[main.TestData2]
5877
{ //object(main.TestData2)
59-
"MyAge2": 0, //int
78+
"MyAge2": 123, //int
6079
"MyTitle2": "example" //string, 标题2
6180
}
6281
],
6382
"data2": { //object(main.TestData2)
64-
"MyAge2": 0, //int
83+
"MyAge2": 123, //int
6584
"MyTitle2": "example" //string, 标题2
6685
},
6786
"my_title": "example" //string, 标题

examples/docs/apis-hello.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@
44

55
## Apis
66

7-
### 测试hello
7+
### @api 测试hello
88

99
```text
1010
GET /hello
1111
```
1212

1313
**Response**:
1414

15-
### 测试hello2
15+
### @api 测试hello2
1616

1717
```text
1818
GET /hello2

examples/docs/apis-ungrouped.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Ungrouped apis
44

55
## Apis
66

7-
### 测试other
7+
### @api 测试other
88

99
```text
1010
GET /other

examples/main.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
package main
22

3-
import "fmt"
3+
import (
4+
"fmt"
5+
6+
"github.com/alovn/apidoc/examples/common"
7+
)
48

59
//@title svc-greeter
610
//@desc greeter接口文档
@@ -24,11 +28,11 @@ type Response struct {
2428
Data interface{} `json:"data,omitempty"` //返回的具体数据
2529
} //通用返回结果
2630

27-
type TestData2 struct { //测试数据2
31+
type TestData2 struct {
2832
MyTitle2 string //标题2
2933
MyAge2 int
3034
}
31-
type TestData struct { //测试数据
35+
type TestData struct {
3236
MyTitle string `json:"my_title,omitempty"` //标题
3337
Data2 *TestData2 `json:"data2,omitempty"`
3438
// MyIntData int
@@ -39,23 +43,24 @@ type TestData struct { //测试数据
3943
}
4044

4145
type Request struct {
42-
ID int `query:"id"`
43-
TID int `param:"tid"`
46+
ID int `query:"id" header:"id" required:"true" example:"12357"` //this id
47+
TID int `param:"tid" validate:"required"`
4448
Name string `json:"name,omitempty"`
4549
Token string `header:"token"`
46-
}
50+
} //请求对象
4751

4852
//@title 测试greeter
4953
//@api GET /greeter
5054
//@group greeter
5155
//@accept json
5256
//@request Request
53-
//@response 200 Response{data=TestData} 输出对象 dd
54-
//@response1 500 Response{code=10010,msg="异常"} 出错了
57+
//@response 200 common.Response{data=TestData} 输出对象 dd
58+
//@response 500 Response{code=10010,msg="异常"} 出错了
5559
//@response1 500 int 错误
56-
func greet() {
60+
func greet() *common.Response {
5761
var msg = "Hello World!"
5862
fmt.Println(msg)
63+
return &common.Response{}
5964
}
6065

6166
//@title 测试greeter2

gen/template/group_apis.tpl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,18 @@
44

55
## Apis
66
{{range $k,$v := .Apis}}
7-
### {{$v.Title}}
7+
### @api {{$v.Title}}
88
{{if $v.Author}}
99
author: {{$v.Author}}
1010
{{end}}
1111
```text
1212
{{$v.HTTPMethod}} {{$v.Api}}
1313
```
14-
14+
{{if $v.Requests.Parameters}}
15+
**Request**:
16+
parameters|type|required|validate|example|description
17+
--|--|--|--|--|--{{range $p:= $v.Requests.Parameters}}
18+
**{{$p.Name}}**|*{{$p.Types}}*|{{$p.Required}}|{{$p.Validate}}|{{$p.Example}}|{{$p.Description}}{{end}}{{end}}
1519
**Response**:
1620
{{range $res := $v.Responses}}
1721
```json

operation.go

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ var (
1313
// responsePattern = regexp.MustCompile(`^(\d+)\s+([\w\-.\\{}=,\[\]]+)\s+(.*)?`)
1414
responsePattern = regexp.MustCompile(`^(\d+)\s+([\w\-.\\{}=,\"\[\]]+|[\w.]+{.*?})\s+(.*)?`)
1515
// responsePattern = regexp.MustCompile(`^([\w,]+)\s+([\w{}]+)\s+([\w\-.\\{}=,\[\]]+)[^"]*(.*)?`)
16-
16+
requestPattern = regexp.MustCompile(`([\w\-.\\\[\]]+)\s*(.*)?`)
1717
// ResponseType{data1=Type1,data2=Type2}.
1818
combinedPattern = regexp.MustCompile(`^([\w\-./\[\]]+){(.*)}$`)
1919
)
@@ -66,6 +66,8 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
6666
operation.ParseTagsComment(lineRemainder)
6767
case apiAttr:
6868
return operation.ParseRouterComment(lineRemainder)
69+
case requestAttr:
70+
return operation.ParseRequestComment(lineRemainder, astFile)
6971
case successAttr, failureAttr, responseAttr:
7072
return operation.ParseResponseComment(lineRemainder, astFile)
7173
case deprecatedAttr:
@@ -113,6 +115,48 @@ func (operation *Operation) ParseRouterComment(commentLine string) error {
113115
return nil
114116
}
115117

118+
func (operation *Operation) ParseRequestComment(commentLine string, astFile *ast.File) error {
119+
fmt.Println("Reqquest comment-------" + commentLine)
120+
matches := requestPattern.FindStringSubmatch(commentLine)
121+
//0 Request 1 Request 2 Comment
122+
if len(matches) != 3 {
123+
return nil
124+
}
125+
refType := matches[1]
126+
switch {
127+
case IsGolangPrimitiveType(refType):
128+
return nil
129+
default:
130+
schema, err := operation.parser.getTypeSchema(refType, astFile, nil, true)
131+
if err != nil {
132+
return err
133+
}
134+
if schema == nil || schema.Properties == nil {
135+
return nil
136+
}
137+
operation.Requests = ApiRequestSpec{
138+
Parameters: map[string]*ApiParameterSpec{},
139+
}
140+
for _, p := range schema.Properties {
141+
for pType, pName := range p.Tags {
142+
if param, ok := operation.Requests.Parameters[pName]; ok {
143+
param.types = append(param.types, pType)
144+
} else {
145+
operation.Requests.Parameters[pName] = &ApiParameterSpec{
146+
Name: pName,
147+
Required: p.Required,
148+
Description: p.Comment,
149+
Validate: p.Validate,
150+
Example: p.Example,
151+
types: []string{pType},
152+
}
153+
}
154+
}
155+
}
156+
return nil
157+
}
158+
}
159+
116160
// ParseResponseComment parses comment for given `response` comment string.
117161
func (operation *Operation) ParseResponseComment(commentLine string, astFile *ast.File) error {
118162
operation.parser.clearStructStack()

parser.go

Lines changed: 5 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ const (
2121
versionAttr = "@version"
2222
descriptionAttr = "@desc"
2323
acceptAttr = "@accept"
24+
requestAttr = "@request"
2425
successAttr = "@success"
2526
failureAttr = "@failure"
2627
responseAttr = "@response"
@@ -358,11 +359,14 @@ func (parser *Parser) getTypeSchema(typeName string, file *ast.File, field *ast.
358359
return &TypeSchema{
359360
Name: name,
360361
FieldName: fieldName,
361-
Comment: field.Comment.Text(),
362+
Comment: strings.TrimSuffix(field.Comment.Text(), "\n"),
362363
FullName: name,
363364
Type: typeName,
364365
Example: getFieldExample(typeName, field),
365366
IsOmitempty: isOmitempty,
367+
Validate: getValidateTagValue(field),
368+
Tags: getParameterTags(field),
369+
Required: getRequiredTagValue(field),
366370
}, nil
367371
}
368372

@@ -549,83 +553,6 @@ func (parser *Parser) parseStructField(file *ast.File, field *ast.Field) (*TypeS
549553
}
550554
return schema, nil
551555
}
552-
553-
// if field.Names == nil {
554-
// typeName, err := getFieldType(field.Type)
555-
// if err != nil {
556-
// return nil, err
557-
// }
558-
559-
// schema, err := parser.getTypeSchema(typeName, file, false)
560-
// if err != nil {
561-
// return nil, err
562-
// }
563-
564-
// if len(schema.Type) > 0 && schema.Type == OBJECT {
565-
// if len(schema.Properties) == 0 {
566-
// return nil, nil
567-
// }
568-
569-
// properties := map[string]*TypeSchema{}
570-
// for k, v := range schema.Properties {
571-
// properties[k] = v
572-
// }
573-
574-
// return properties, nil
575-
// }
576-
577-
// // for alias type of non-struct types ,such as array,map, etc. ignore field tag.
578-
// // return map[string]*TypeSchema{Type: typeName}, nil, nil
579-
// }
580-
581-
// ps := parser.fieldParserFactory(parser, field)
582-
583-
// if ps.ShouldSkip() {
584-
// return nil, nil, nil
585-
// }
586-
587-
// fieldName, err := ps.FieldName()
588-
// if err != nil {
589-
// return nil, nil, err
590-
// }
591-
592-
// schema, err := ps.CustomSchema()
593-
// if err != nil {
594-
// return nil, nil, err
595-
// }
596-
597-
// if schema == nil {
598-
// typeName, err := getFieldType(field.Type)
599-
// if err == nil {
600-
// // named type
601-
// schema, err = parser.getTypeSchema(typeName, file, true)
602-
// } else {
603-
// // unnamed type
604-
// schema, err = parser.parseTypeExpr(file, field.Type, false)
605-
// }
606-
607-
// if err != nil {
608-
// return nil, nil, err
609-
// }
610-
// }
611-
612-
// err = ps.ComplementSchema(schema)
613-
// if err != nil {
614-
// return nil, nil, err
615-
// }
616-
617-
// var tagRequired []string
618-
619-
// required, err := ps.IsRequired()
620-
// if err != nil {
621-
// return nil, nil, err
622-
// }
623-
624-
// if required {
625-
// tagRequired = append(tagRequired, fieldName)
626-
// }
627-
628-
// return map[string]*TypeSchema{fieldName: *schema}, tagRequired, nil
629556
}
630557

631558
func getFieldType(field ast.Expr) (isArray bool, typeName string, err error) {

0 commit comments

Comments
 (0)