Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

deprecate some parts of routers in an operation #1735

Merged
merged 1 commit into from
Jan 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 20 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -425,25 +425,26 @@ When a short string in your documentation is insufficient, or you need images, c
[celler/controller](https://github.com/swaggo/swag/tree/master/example/celler/controller)


| annotation | description |
|-------------|----------------------------------------------------------------------------------------------------------------------------|
| description | A verbose explanation of the operation behavior. |
| description.markdown | A short description of the application. The description will be read from a file. E.g. `@description.markdown details` will load `details.md`| // @description.file endpoint.description.markdown |
| id | A unique string used to identify the operation. Must be unique among all API operations. |
| tags | A list of tags to each API operation that separated by commas. |
| summary | A short summary of what the operation does. |
| accept | A list of MIME types the APIs can consume. Note that Accept only affects operations with a request body, such as POST, PUT and PATCH. Value MUST be as described under [Mime Types](#mime-types). |
| produce | A list of MIME types the APIs can produce. Value MUST be as described under [Mime Types](#mime-types). |
| param | Parameters that separated by spaces. `param name`,`param type`,`data type`,`is mandatory?`,`comment` `attribute(optional)` |
| security | [Security](#security) to each API operation. |
| success | Success response that separated by spaces. `return code or default`,`{param type}`,`data type`,`comment` |
| failure | Failure response that separated by spaces. `return code or default`,`{param type}`,`data type`,`comment` |
| response | As same as `success` and `failure` |
| header | Header in response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| router | Path definition that separated by spaces. `path`,`[httpMethod]` |
| x-name | The extension key, must be start by x- and take only json value. |
| x-codeSample | Optional Markdown usage. take `file` as parameter. This will then search for a file named like the summary in the given folder. |
| deprecated | Mark endpoint as deprecated. |
| annotation | description |
|----------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| description | A verbose explanation of the operation behavior. |
| description.markdown | A short description of the application. The description will be read from a file. E.g. `@description.markdown details` will load `details.md` | // @description.file endpoint.description.markdown |
| id | A unique string used to identify the operation. Must be unique among all API operations. |
| tags | A list of tags to each API operation that separated by commas. |
| summary | A short summary of what the operation does. |
| accept | A list of MIME types the APIs can consume. Note that Accept only affects operations with a request body, such as POST, PUT and PATCH. Value MUST be as described under [Mime Types](#mime-types). |
| produce | A list of MIME types the APIs can produce. Value MUST be as described under [Mime Types](#mime-types). |
| param | Parameters that separated by spaces. `param name`,`param type`,`data type`,`is mandatory?`,`comment` `attribute(optional)` |
| security | [Security](#security) to each API operation. |
| success | Success response that separated by spaces. `return code or default`,`{param type}`,`data type`,`comment` |
| failure | Failure response that separated by spaces. `return code or default`,`{param type}`,`data type`,`comment` |
| response | As same as `success` and `failure` |
| header | Header in response that separated by spaces. `return code`,`{param type}`,`data type`,`comment` |
| router | Path definition that separated by spaces. `path`,`[httpMethod]` |
| deprecatedrouter | As same as router, but deprecated. |
| x-name | The extension key, must be start by x- and take only json value. |
| x-codeSample | Optional Markdown usage. take `file` as parameter. This will then search for a file named like the summary in the given folder. |
| deprecated | Mark endpoint as deprecated. |



Expand Down
32 changes: 17 additions & 15 deletions README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -378,23 +378,25 @@ swag fmt -d ./ --exclude ./internal

Example [celler/controller](https://github.com/swaggo/swag/tree/master/example/celler/controller)

| 注释 | 描述 |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| description | 操作行为的详细说明。 |
| description.markdown | 应用程序的简短描述。该描述将从名为`endpointname.md`的文件中读取。 |
| id | 用于标识操作的唯一字符串。在所有API操作中必须唯一。 |
| tags | 每个API操作的标签列表,以逗号分隔。 |
| 注释 | 描述 |
|----------------------|------------------------------------------------------------------------------------------------|
| description | 操作行为的详细说明。 |
| description.markdown | 应用程序的简短描述。该描述将从名为`endpointname.md`的文件中读取。 |
| id | 用于标识操作的唯一字符串。在所有API操作中必须唯一。 |
| tags | 每个API操作的标签列表,以逗号分隔。 |
| summary | 该操作的简短摘要。 |
| accept | API 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“[Mime类型](#mime类型)”中所述。 |
| produce | API可以生成的MIME类型的列表。值必须如“[Mime类型](#mime类型)”中所述。 |
| accept | API 可以使用的 MIME 类型列表。 请注意,Accept 仅影响具有请求正文的操作,例如 POST、PUT 和 PATCH。 值必须如“[Mime类型](#mime类型)”中所述。 |
| produce | API可以生成的MIME类型的列表。值必须如“[Mime类型](#mime类型)”中所述。 |
| param | 用空格分隔的参数。`param name`,`param type`,`data type`,`is mandatory?`,`comment` `attribute(optional)` |
| security | 每个API操作的[安全性](#安全性)。 |
| success | 以空格分隔的成功响应。`return code`,`{param type}`,`data type`,`comment` |
| failure | 以空格分隔的故障响应。`return code`,`{param type}`,`data type`,`comment` |
| response | 与success、failure作用相同 |
| header | 以空格分隔的头字段。 `return code`,`{param type}`,`data type`,`comment` |
| router | 以空格分隔的路径定义。 `path`,`[httpMethod]` |
| x-name | 扩展字段必须以`x-`开头,并且只能使用json值。 |
| security | 每个API操作的[安全性](#安全性)。 |
| success | 以空格分隔的成功响应。`return code`,`{param type}`,`data type`,`comment` |
| failure | 以空格分隔的故障响应。`return code`,`{param type}`,`data type`,`comment` |
| response | 与success、failure作用相同 |
| header | 以空格分隔的头字段。 `return code`,`{param type}`,`data type`,`comment` |
| router | 以空格分隔的路径定义。 `path`,`[httpMethod]` |
| deprecatedrouter | 与router相同,但是是deprecated的。 |
| x-name | 扩展字段必须以`x-`开头,并且只能使用json值。 |
| deprecated | 将当前API操作的所有路径设置为deprecated |

## Mime类型

Expand Down
8 changes: 6 additions & 2 deletions operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
type RouteProperties struct {
HTTPMethod string
Path string
Deprecated bool
}

// Operation describes a single API operation on a path.
Expand Down Expand Up @@ -147,7 +148,9 @@ func (operation *Operation) ParseComment(comment string, astFile *ast.File) erro
case headerAttr:
return operation.ParseResponseHeaderComment(lineRemainder, astFile)
case routerAttr:
return operation.ParseRouterComment(lineRemainder)
return operation.ParseRouterComment(lineRemainder, false)
case deprecatedRouterAttr:
return operation.ParseRouterComment(lineRemainder, true)
case securityAttr:
return operation.ParseSecurityComment(lineRemainder)
case deprecatedAttr:
Expand Down Expand Up @@ -707,7 +710,7 @@ func parseMimeTypeList(mimeTypeList string, typeList *[]string, format string) e
var routerPattern = regexp.MustCompile(`^(/[\w./\-{}+:$]*)[[:blank:]]+\[(\w+)]`)

// ParseRouterComment parses comment for given `router` comment string.
func (operation *Operation) ParseRouterComment(commentLine string) error {
func (operation *Operation) ParseRouterComment(commentLine string, deprecated bool) error {
matches := routerPattern.FindStringSubmatch(commentLine)
if len(matches) != 3 {
return fmt.Errorf("can not parse router comment \"%s\"", commentLine)
Expand All @@ -716,6 +719,7 @@ func (operation *Operation) ParseRouterComment(commentLine string) error {
signature := RouteProperties{
Path: matches[1],
HTTPMethod: strings.ToUpper(matches[2]),
Deprecated: deprecated,
}

if _, ok := allMethod[signature.HTTPMethod]; !ok {
Expand Down
15 changes: 15 additions & 0 deletions operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import (
"go/ast"
goparser "go/parser"
"go/token"
"os"
"path/filepath"
"testing"

"github.com/go-openapi/spec"
Expand Down Expand Up @@ -2416,3 +2418,16 @@ func TestParseCodeSamples(t *testing.T) {
assert.Error(t, err, "no error should be thrown")
})
}

func TestParseDeprecatedRouter(t *testing.T) {
p := New()
searchDir := "./testdata/deprecated_router"
if err := p.ParseAPI(searchDir, mainAPIFile, defaultParseDepth); err != nil {
t.Error("Failed to parse api: " + err.Error())
}

b, _ := json.MarshalIndent(p.swagger, "", " ")
expected, err := os.ReadFile(filepath.Join(searchDir, "expected.json"))
assert.NoError(t, err)
assert.Equal(t, expected, b)
}
5 changes: 5 additions & 0 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const (
headerAttr = "@header"
tagsAttr = "@tags"
routerAttr = "@router"
deprecatedRouterAttr = "@deprecatedrouter"
summaryAttr = "@summary"
deprecatedAttr = "@deprecated"
securityAttr = "@security"
Expand Down Expand Up @@ -1081,6 +1082,10 @@ func processRouterOperation(parser *Parser, operation *Operation) error {
*op = &operation.Operation
}

if routeProperties.Deprecated {
(*op).Deprecated = routeProperties.Deprecated
}

parser.swagger.Paths.Paths[routeProperties.Path] = pathItem
}

Expand Down
17 changes: 17 additions & 0 deletions testdata/deprecated_router/api/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package api

import "net/http"

// @Description add Foo
// @Deprecated
// @Success 200 {string} string
// @Router /testapi/foo1 [put]
// @Router /testapi/foo1 [post]
// @Router /test/api/foo1 [post]
func AddFoo(w http.ResponseWriter, r *http.Request) {}

// @Description get Foo
// @Success 200 {string} string
// @Router /testapi/foo1 [get]
// @DeprecatedRouter /test/api/foo1 [get]
func GetFoo(w http.ResponseWriter, r *http.Request) {}
75 changes: 75 additions & 0 deletions testdata/deprecated_router/expected.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{
"swagger": "2.0",
"info": {
"description": "test data for deprecated router",
"title": "Swagger Example API",
"termsOfService": "http://swagger.io/terms/",
"contact": {},
"version": "1.0"
},
"paths": {
"/test/api/foo1": {
"get": {
"description": "get Foo",
"deprecated": true,
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
},
"post": {
"description": "add Foo",
"deprecated": true,
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
}
},
"/testapi/foo1": {
"get": {
"description": "get Foo",
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
},
"put": {
"description": "add Foo",
"deprecated": true,
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
},
"post": {
"description": "add Foo",
"deprecated": true,
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "string"
}
}
}
}
}
}
}
9 changes: 9 additions & 0 deletions testdata/deprecated_router/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package main

// @title Swagger Example API
// @version 1.0
// @description test data for deprecated router
// @termsOfService http://swagger.io/terms/

func main() {
}