Skip to content

Commit

Permalink
Swagger update
Browse files Browse the repository at this point in the history
  • Loading branch information
zodial committed Oct 18, 2024
1 parent 744362a commit d77a93f
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 16 deletions.
55 changes: 41 additions & 14 deletions console/commands/swagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ func (SwaggerCommand) Configure() command.Configure {
Description: "指定文档语言,如说明的下一行是‘// @lang:en name’则‘name’代替原说明",
Default: "",
},
{
Name: "host",
Description: "指定接口Host",
Default: "",
},
},
},
}
Expand All @@ -55,6 +60,7 @@ func (SwaggerCommand) Execute(input command.Input) {
out := input.GetOption("out")
path := input.GetOption("path")
language = input.GetOption("lang")
host := input.GetOption("host")

swagger := openapi.Spec{
Swagger: "2.0",
Expand All @@ -70,33 +76,54 @@ func (SwaggerCommand) Execute(input command.Input) {
Extensions: nil,
GlobalOptions: nil,
}
if host != "" {
re := regexp.MustCompile(`^(https?)://(.+)`)
matches := re.FindStringSubmatch(host)
if matches != nil {
swagger.Schemes = []string{matches[1]}
swagger.Host = matches[2]
} else {
swagger.Host = host
}
}
if parser.DirIsExist(source) {
data, _ := os.ReadFile(source)
json.Unmarshal(data, &swagger)
}

allProtoc := parser.NewProtocParserForDir(path)
for s, parsers := range allProtoc {
prefix := getPrefix(path, s)
pkg := getPackage(path, s)
for _, fileParser := range parsers {
for _, message := range fileParser.Messages {
name, parameter := messageToSchemas(prefix, message, &swagger)
name, parameter := messageToSchemas(pkg, message, &swagger)
swagger.Definitions[defName(name)] = parameter
}
for _, enum := range fileParser.Enums {
name, parameter := enumToMessage(prefix, enum)
name, parameter := enumToMessage(pkg, enum)
swagger.Definitions[defName(name)] = parameter
}

}
}
// 全局定义后在生成url
for s, parsers := range allProtoc {
prefix := getPrefix(path, s)
pkg := getPackage(path, s)
for _, fileParser := range parsers {
for _, service := range fileParser.Services {
var prefix string
if routeGroup, ok := service.Opt["http.RouteGroup"]; ok {
prefix = "/$[" + routeGroup.Val + "]"
if routeGroup.Doc != "" {
re := regexp.MustCompile(`(?i)@prefix=(\w+)`)
match := re.FindStringSubmatch(routeGroup.Doc)
if match != nil {
prefix = "/" + match[1]
}
}
}
for _, rpc := range service.Rpc {
rpcToPath(prefix, rpc, &swagger, parsers, allProtoc, service.Opt)
rpcToPath(pkg, rpc, &swagger, parsers, allProtoc, prefix)
}
}
}
Expand Down Expand Up @@ -180,16 +207,16 @@ func isValidHTTPStatusCode(code int) bool {
return code >= 100 && code <= 599
}

func rpcToPath(pge string, service parser.ServiceRpc, swagger *openapi.Spec, nowDirProtoc []parser.ProtocFileParser, allProtoc map[string][]parser.ProtocFileParser, serviceOpt map[string]parser.Option) {
func rpcToPath(pge string, service parser.ServiceRpc, swagger *openapi.Spec, nowDirProtoc []parser.ProtocFileParser, allProtoc map[string][]parser.ProtocFileParser, prefix string) {
service.Doc = filterLanguage(service.Doc)
for _, options := range service.Opt {
for _, option := range options {
urlPath := option.Val
if urlPath == "" {
urlPath = getUrl(service.Opt)
}
if routeGroup, ok := serviceOpt["http.RouteGroup"]; ok {
urlPath = "$[" + routeGroup.Val + "]" + urlPath
if prefix != "" {
urlPath = prefix + urlPath
}
var path = &openapi.Path{}
if o, ok := swagger.Paths[urlPath]; ok {
Expand Down Expand Up @@ -562,7 +589,7 @@ func getProtoToSwagger(t string) string {
return "object"
}

func getPrefix(path, s string) string {
func getPackage(path, s string) string {
got := strings.ReplaceAll(s, path, "")
got = strings.Trim(got, "/")
got = strings.ReplaceAll(got, "/", ".")
Expand Down Expand Up @@ -635,12 +662,12 @@ func filterRequired(doc string) (string, bool) {
return strings.Join(newArr, "\n"), isRequired
}

// 仅支持string和number兼容两种写法 @example:xxx xxx 或 @example(xxx xxx)
// 仅支持string和number兼容两种写法 @example=xxx 或 @example(xxx xxx)
func filterExample(doc string, ty string) (string, interface{}) {
arr := strings.Split(doc, "\n")
var newArr []string
var example string
re := regexp.MustCompile(`(?i)\s*//\s*@example=(.*)`)
re := regexp.MustCompile(`(?i)\s*//\s*@example=(.*|\("*[^)]+"*)`)
re2 := regexp.MustCompile(`(?i)[/\s]*@example\((.*)\)\s*`)
for _, s := range arr {
matches := re.FindStringSubmatch(s)
Expand Down Expand Up @@ -671,7 +698,7 @@ func filterExample(doc string, ty string) (string, interface{}) {
return strings.Join(newArr, "\n"), result
}

// 首行为默认说明,次行如://@lang:zh xxx 中的 xxx 将替换默认说明
// 首行为默认说明,次行如://@lang=zh xxx 中的 xxx 将替换默认说明
func filterLanguage(doc string) string {
arr := strings.Split(doc, "\n")
if len(arr) < 2 {
Expand Down Expand Up @@ -721,8 +748,8 @@ func parseTag(str string) string {
return strings.Join(newArr, " \n")
}

// 例:@query=id @lang=zh @format:string @example=abc 用户ID
// format默认为int,如format是对象或枚举,即使本地引用,也必须要加上包名,如@format:api.UserStatus
// 例:@query=id @lang=zh @format=string @example=abc 用户ID
// format默认为int,如format是对象或枚举,即使本地引用,也必须要加上包名,如@format=api.UserStatus
func parseParamInPath(option parser.Option) (params openapi.Parameters) {
re := regexp.MustCompile(`:([a-zA-Z_][a-zA-Z0-9_]*)`)
matches := re.FindAllStringSubmatch(option.Val, -1)
Expand Down
13 changes: 11 additions & 2 deletions docs/swagger.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@
### 2024-10-16 更新

1. post的payload统一改为application/json
2. 支持多语言,新增执行参数-lang=语言标识,以`//@lang=语言 说明`声明指定语言说明
2. 支持多语言,新增执行参数`-lang=语言标识`,以`//@lang=语言 说明`声明指定语言说明
3. 优化Description显示,tag换行显示,引用对象时采用本地说明
4. 支持example定义,用`//@example=”或“//@example()`声明,前者不支持空格
5. 增加path的参数及说明,于请求声明上一行添加注释,例如:`option (http.Get) = "/user/:id";`,上一行添加:`// @query=id @lang=语言标识 @format=string @example=ABC 说明文本`,其中query是必须指定声明,format默认为int
5. 增加path的参数及说明,于请求声明上一行添加注释,例如:`option (http.Get) = "/user/:id";`,上一行添加:`// @query=id @lang=语言标识 @format=string @example=ABC 说明文本`,其中query是必须指定声明,format默认为int

### 2024-10-18 更新

1. 在路由组声明上一行加上注释`@prefix=xxx`即可指定当前protobuf文件生成的swagger的接口前缀为`xxx`,该注释仅文档使用,应与业务代码一致)
```
// @prefix=api
option (http.RouteGroup) = "api";
```
2. 新增执行参数`-host=接口host`,接口host以`http://``https://`开头则指定协议,只填域名则两者都支持

0 comments on commit d77a93f

Please sign in to comment.