## Golang不一样的swagger
### 什么是swagger
Swagger 是一个规范且完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
### swag
[zc2638/swag](https://github.com/zc2638/swag) 是一个轻量级的库,可以为Go项目生成swagger json。
没有代码生成,没有框架约束,无须使用注释信息去实现伪注解,只有一个简单的swagger结构定义。
原始代码库savaki/swag,由于作者不再维护,故在此基础上的修改版本。
### 使用
#### 获取
```
go get github.com/zc2638/swag
```
#### Endpoint
swag提供了一个单独的程序包,endpoint用来创建一个特定的接口定义,这些接口定义可以通过swag.Endpoints(...)挂载。
在这个简单的示例中,我们生成一个接口定义来获取所有pet。接口定义只需要接口请求方式和路径,为了使swagger定义完整,需要约束返回结果。
```go
allPets := endpoint.New(http.MethodGet, "/pet", endpoint.ResponseSuccess())
```
当然,也可以指定多个自定义返回结果:
```go
allPets := endpoint.New("get", "/pet",
endpoint.Summary("Return all the pets"),
endpoint.Response(http.StatusOk, Pet{}, "Successful operation"),
endpoint.Response(http.StatusInternalServerError, Error{}, "Oops ... something went wrong"),
)
```
#### Walk
Walk是简化所有接口定义遍历的方法。有关如何使用Walk方法将接口定义绑定到指定框架的路由上,请参见下面的完整示例。
```go
api := swag.New(
swag.Title("Swagger Petstore"),
swag.Endpoints(post, get),
)
router := gin.Default()
// iterate over each endpoint, if we've defined a handler, we can use it to bind to the router. We're using ```gin``
// in this example, but any web framework will do.
api.Walk(func(path string, endpoint *swagger.Endpoint) {
h := endpoint.Handler.(func(c *gin.Context))
path = swag.ColonPath(path)
router.Handle(endpoint.Method, path, h)
})
```
#### 完整示例
```go
// Copyright 2020 zc2638
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
package main
import (
"io"
"net/http"
"github.com/zc2638/swag"
"github.com/zc2638/swag/endpoint"
"github.com/zc2638/swag/swagger"
)
func handle(w http.ResponseWriter, req *http.Request) {
io.WriteString(w, req.Method+" - Insert your code here")
}
// Category example from the swagger pet store
type Category struct {
ID int64 `json:"category"`
Name string `json:"name" enum:"dog,cat"`
}
// Pet example from the swagger pet store
type Pet struct {
ID int64 `json:"id"`
Category Category `json:"category"`
Name string `json:"name" required:"" example:"张三" desc:"名称"`
PhotoUrls []string `json:"photoUrls"`
Tags []string `json:"tags"`
Test
}
type Test struct {
A string `json:"a"`
}
func main() {
post := endpoint.New("post", "/pet", endpoint.Summary("Add a new pet to the store"),
endpoint.Handler(handle),
endpoint.Description("Additional information on adding a pet to the store"),
endpoint.Body(Pet{}, "Pet object that needs to be added to the store", true),
endpoint.Response(http.StatusOK, "Successfully added pet", endpoint.Schema(Pet{})),
endpoint.Security("petstore_auth", "read:pets", "write:pets"),
)
get := endpoint.New("get", "/pet/{petId}", endpoint.Summary("Find pet by ID"),
endpoint.Handler(handle),
endpoint.Path("petId", "integer", "ID of pet to return", true),
endpoint.Response(http.StatusOK, "successful operation", endpoint.Schema(Pet{})),
endpoint.Security("petstore_auth", "read:pets"),
)
api := swag.New(
swag.Endpoints(post, get),
swag.Security("petstore_auth", "read:pets"),
swag.SecurityScheme("petstore_auth",
swagger.OAuth2Security("accessCode", "http://example.com/oauth/authorize", "http://example.com/oauth/token"),
swagger.OAuth2Scope("write:pets", "modify pets in your account"),
swagger.OAuth2Scope("read:pets", "read your pets"),
),
)
for path, endpoints := range api.Paths {
http.Handle(path, endpoints)
}
enableCors := true
http.Handle("/swagger", api.Handler(enableCors))
http.ListenAndServe(":8080", nil)
}
```
可以使用内置方法```swag.New().Handler(false)```生成解析好的Swagger JSON定义。
指定Struct Tag生成额外内容:
- required: 是否必须
- desc: 描述
- description: 描述,作用同desc
- example: 默认示例
- enum: 枚举定义,逗号分隔
### 快速生成在线版本swagger
[参考官方UI](https://github.com/swagger-api/swagger-ui)
#### Webpack
[参考](https://github.com/swagger-api/swagger-ui/tree/master/docs/samples/webpack-getting-started)
#### Docker
> docker run -p 8080:8080 -e SWAGGER\_JSON\_URL=https://petstore.swagger.io/v1/swagger.json swaggerapi/swagger-ui
#### Kubernetes
swagger-ui.yaml
```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: swagger-ui
labels:
app: swagger-ui
spec:
selector:
matchLabels:
app: swagger-ui
template:
metadata:
name: swagger-ui
labels:
app: swagger-ui
spec:
containers:
- name: swagger-ui
image: swaggerapi/swagger-ui:latest
env:
- name: SWAGGER_JSON_URL
value: 'https://petstore.swagger.io/v1/swagger.json'
---
apiVersion: v1
kind: Service
metadata:
name: swagger-ui
labels:
app: swagger-ui
spec:
ports:
- name: swagger-ui-80
port: 80
selector:
app: swagger-ui
type: NodePort
```
> kubectl app -f swagger-ui.yaml
<img width="100%" src="https://static.studygolang.com/210111/e908853fb0786972884954733597f9f0.png" />
### 最后
传送门:[**https://github.com/zc2638/swag**](https://github.com/zc2638/swag)