Skip to content

Commit

Permalink
root level accept/produce params (#1011)
Browse files Browse the repository at this point in the history
* root level accept/produce params

* update README.md
  • Loading branch information
ubogdan authored Oct 3, 2021
1 parent 1a4da01 commit 9fb19d0
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,8 @@ $ swag init
| license.url | A URL to the license used for the API. MUST be in the format of a URL. | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
| host | The host (name or ip) serving the API. | // @host localhost:8080 |
| BasePath | The base path on which the API is served. | // @BasePath /api/v1 |
| accept | A list of MIME types the APIs can consume. Value MUST be as described under [Mime Types](#mime-types). | // @accept json |
| produce | A list of MIME types the APIs can produce. Value MUST be as described under [Mime Types](#mime-types). | // @produce json |
| query.collection.format | The default collection(array) param format in query,enums:csv,multi,pipes,tsv,ssv. If not set, csv is the default.| // @query.collection.format multi
| schemes | The transfer protocol for the operation that separated by spaces. | // @schemes http https |
| x-name | The extension key, must be start by x- and take only json value | // @x-example-key {"key": "value"} |
Expand Down
2 changes: 2 additions & 0 deletions README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,8 @@ swag init
| license.url | 用于API的许可证的URL。 必须采用网址格式。 | // @license.url http://www.apache.org/licenses/LICENSE-2.0.html |
| host | 运行API的主机(主机名或IP地址)。 | // @host localhost:8080 |
| BasePath | 运行API的基本路径。 | // @BasePath /api/v1 |
| accept | API可以使用的MIME类型的列表。值必须如“[Mime类型](#mime-types)”中所述。 | // @accept json |
| produce | API可以生成的MIME类型的列表。值必须如“[Mime类型](#mime-types)”中所述。 | // @produce json |
| query.collection.format | 请求URI query里数组参数的默认格式:csv,multi,pipes,tsv,ssv。 如果未设置,则默认为csv。 | // @query.collection.format multi |
| schemes | 用空格分隔的请求的传输协议。 | // @schemes http https |
| x-name | 扩展的键必须以x-开头,并且只能使用json值 | // @x-example-key {"key": "value"} |
Expand Down
4 changes: 2 additions & 2 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
operation.ID = lineRemainder
case "@tags":
operation.ParseTagsComment(lineRemainder)
case "@accept":
case acceptAttr:
err = operation.ParseAcceptComment(lineRemainder)
case "@produce":
case produceAttr:
err = operation.ParseProduceComment(lineRemainder)
case "@param":
err = operation.ParseParamComment(lineRemainder, astFile)
Expand Down
30 changes: 26 additions & 4 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ const (
// SnakeCase indicates using SnakeCase strategy for struct field.
SnakeCase = "snakecase"

acceptAttr = "@accept"
produceAttr = "@produce"
scopeAttrPrefix = "@scope."
)

Expand Down Expand Up @@ -300,10 +302,10 @@ func (parser *Parser) ParseGeneralAPIInfo(mainAPIFile string) error {
parser.swagger.Swagger = "2.0"

for _, comment := range fileTree.Comments {
if !isGeneralAPIComment(comment) {
comments := strings.Split(comment.Text(), "\n")
if !isGeneralAPIComment(comments) {
continue
}
comments := strings.Split(comment.Text(), "\n")
err := parseGeneralAPIInfo(parser, comments)
if err != nil {
return err
Expand Down Expand Up @@ -360,6 +362,16 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
parser.swagger.Host = value
case "@basepath":
parser.swagger.BasePath = value
case acceptAttr:
err := parser.ParseAcceptComment(value)
if err != nil {
return err
}
case produceAttr:
err := parser.ParseProduceComment(value)
if err != nil {
return err
}
case "@schemes":
parser.swagger.Schemes = getSchemes(commentLine)
case "@tag.name":
Expand Down Expand Up @@ -473,8 +485,18 @@ func parseGeneralAPIInfo(parser *Parser, comments []string) error {
return nil
}

func isGeneralAPIComment(comment *ast.CommentGroup) bool {
for _, commentLine := range strings.Split(comment.Text(), "\n") {
// ParseAcceptComment parses comment for given `accept` comment string.
func (parser *Parser) ParseAcceptComment(commentLine string) error {
return parseMimeTypeList(commentLine, &parser.swagger.Consumes, "%v accept type can't be accepted")
}

// ParseProduceComment parses comment for given `produce` comment string.
func (parser *Parser) ParseProduceComment(commentLine string) error {
return parseMimeTypeList(commentLine, &parser.swagger.Produces, "%v produce type can't be accepted")
}

func isGeneralAPIComment(comments []string) bool {
for _, commentLine := range comments {
attribute := strings.ToLower(strings.Split(commentLine, " ")[0])
switch attribute {
// The @summary, @router, @success,@failure annotation belongs to Operation
Expand Down
66 changes: 66 additions & 0 deletions parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -383,6 +383,72 @@ func TestParser_ParseGeneralApiInfoFailed(t *testing.T) {
assert.Error(t, p.ParseGeneralAPIInfo("testdata/noexist.go"))
}

func TestParser_ParseAcceptComment(t *testing.T) {
t.Parallel()

expected := []string{
"application/json",
"text/xml",
"text/plain",
"text/html",
"multipart/form-data",
"application/x-www-form-urlencoded",
"application/vnd.api+json",
"application/x-json-stream",
"application/octet-stream",
"image/png",
"image/jpeg",
"image/gif",
"application/xhtml+xml",
"application/health+json",
}

comment := `@Accept json,xml,plain,html,mpfd,x-www-form-urlencoded,json-api,json-stream,octet-stream,png,jpeg,gif,application/xhtml+xml,application/health+json`

parser := New()
assert.NoError(t, parseGeneralAPIInfo(parser, []string{comment}))
assert.Equal(t, parser.swagger.Consumes, expected)

assert.Error(t, parseGeneralAPIInfo(parser, []string{`@Accept cookies,candies`}))

parser = New()
assert.NoError(t, parser.ParseAcceptComment(comment[len(acceptAttr)+1:]))
assert.Equal(t, parser.swagger.Consumes, expected)
}

func TestParser_ParseProduceComment(t *testing.T) {
t.Parallel()

expected := []string{
"application/json",
"text/xml",
"text/plain",
"text/html",
"multipart/form-data",
"application/x-www-form-urlencoded",
"application/vnd.api+json",
"application/x-json-stream",
"application/octet-stream",
"image/png",
"image/jpeg",
"image/gif",
"application/xhtml+xml",
"application/health+json",
}

comment := `@Produce json,xml,plain,html,mpfd,x-www-form-urlencoded,json-api,json-stream,octet-stream,png,jpeg,gif,application/xhtml+xml,application/health+json`

parser := New()
assert.NoError(t, parseGeneralAPIInfo(parser, []string{comment}))
assert.Equal(t, parser.swagger.Produces, expected)

assert.Error(t, parseGeneralAPIInfo(parser, []string{`@Produce cookies,candies`}))

parser = New()
assert.NoError(t, parser.ParseProduceComment(comment[len(produceAttr)+1:]))
assert.Equal(t, parser.swagger.Produces, expected)
}

func TestParser_ParseGeneralAPIInfoCollectionFromat(t *testing.T) {
t.Parallel()

Expand Down

0 comments on commit 9fb19d0

Please sign in to comment.