go-swagger 规范
// swagger:operation PUT /api/v1/addr/update/{id} addr del
// summary: 修改用户地址
// description: 修改指定用户的addr
// parameters:
// - name: token
// in: header
// description: token
// type: string
// required: true
// - name: id
// in: path
// description: 地址id
// type: string
// required: true
// - name: addr
// in: body
// description: addr
// type: string
// required: true
// responses:
// 200: repoResp
// 400: badReq
// swagger:operaion [请求方式(可以是GET\PUT\DELETE\POST\PATCH)] [url:请求地址] [tag] [operation id] (同一标签的属于同一类,)
// summary: 标题
// description: 描述
// parametres: 下面是参数了
// - name: 参数名
in: [header|body|query|path] 参数的位置
description: 描述
type: 类型
required: 是否必须
// responses: 响应
// 200:
// 404:
走通流程
package main
import (
"net/http"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
func main() {
e := gin.Default()
e.Use(cors.Default())
// swagger:route GET /ping tag ping
// summary: ping
// description: ping
// responses:
// default: default
// 200: ok
// 400: s400
// 500: s500
e.GET("/ping", func(context *gin.Context) {
context.String(http.StatusOK, "%s", "pong")
})
e.Run(":10100")
}
使用
进入项目根目录
swagger generate spec -o ./swagger.json // 根据swagger规范 创建 swagger.json 规范文档
swagger serve -F=swagger swagger.json // 启动一个http服务
在该页面中,可以尝试做请求,不过可以看到,这里的 host 指向是错的,这里后面会提到
generation rule
swagger:meta
meta注释将一个文件标记为API元数据的源文件
// version: 1.0.0
// schemas: http, https
// basePath: /
// host: 127.0.0.1:10100
// securityDefinitions:
// cookie_header:
// type: apiKey
// name: Cookie
// in: header
// security:
// - cookie_header:
//
// consumes: # 发送的类型
// - application/json
// produces: # 接收的类型
// - application/json
// License:
// name: xxx
// url: xxx
// Contact:
// name: API Support
// url: http://www.swagger.io/support
// email: support@swagger.io
// swagger:meta
package classification
swagger:model
Syntax swagger:model [?model name]
// swagger:model
type User struct {
// the id for this user
//
// required: true
// min: 1
ID int64 `json:"id"`
// the name for this user
// required: true
// min length: 3
Name string `json:"name"`
// the email address for this user
//
// required: true
// example: user@provider.net
Email strfmt.Email `json:"login"`
// the friends for this user
Friends []User `json:"friends"`
}
swagger:parameters
- Syntax swagger:parameters [operationid1 operationid2]
// swagger:parameters postPing
type Consumer struct {
// Name of the consumer, should be unique among all applications in the same control plane.
// required: true
// example: jack
// min length: 1
// max length: 100
// pattern: ^[a-zA-Z0-9_]+$
// in: body
Name string `json:"name"`
// Description for this consumer.
// min length: 1
// max length: 256
// example: jack is the most important API consumer.
// in: body
Description string `json:"description,omitempty"`
}
流程加强-1
上面有提到,swagger-ui 中 请求的url指向不对,这时,我们可以通过 swagger:meta解决
// version: 1.0.0
// schemas: https
// basePath: /
// host: 127.0.0.1:10100
// securityDefinitions:
// cookie_header:
// type: apiKey
// name: Cookie
// in: header
// security:
// - cookie_header:
//
// consumes:
// - application/json
// produces:
// - application/json
//
// swagger:meta
package main
import (
"net/http"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
func main() {
e := gin.Default()
e.Use(cors.Default())
// swagger:route GET /ping tag ping
// summary: ping
// description: ping
// responses:
// default: default
// 200: ok
// 400: s400
// 500: s500
e.GET("/ping", func(context *gin.Context) {
context.String(http.StatusOK, "%s", "pong")
})
e.Run(":10100")
}
流程加强-2
当请求参数比较复杂时,如何在swagger 中给出相应的提示?使用swagger:parameters
// version: 1.0.0
// schemas: https
// basePath: /
// host: 127.0.0.1:10100
// securityDefinitions:
// cookie_header:
// type: apiKey
// name: Cookie
// in: header
// security:
// - cookie_header:
//
// consumes:
// - application/json
// produces:
// - application/json
//
// swagger:meta
package main
import (
"net/http"
"github.com/gin-contrib/cors"
"github.com/gin-gonic/gin"
)
// swagger:parameters postPing (如果有多个请求都用到了该结构,多个operationID 用空格分开)
type Consumer struct {
// Name of the consumer, should be unique among all applications in the same control plane.
// required: true
// example: jack
// min length: 1
// max length: 100
// pattern: ^[a-zA-Z0-9_]+$
// in: body
Name string `json:"name"`
// Description for this consumer.
// min length: 1
// max length: 256
// example: jack is the most important API consumer.
// in: body
Description string `json:"description,omitempty"`
// required: true
// in: body
C1 Consumer1
}
type Consumer1 struct {
// in: body
A string
// in: body
B string
}
func main() {
e := gin.Default()
e.Use(cors.Default())
// swagger:route GET /ping ping getPing
// summary: ping
// description: ping
// responses:
// default: default
// 200: ok
// 400: s400
// 500: s500
e.GET("/ping", func(context *gin.Context) {
var model Consumer
if err := context.BindJSON(&model); err != nil {
context.AbortWithStatusJSON(http.StatusBadRequest, "params error")
return
}
context.String(http.StatusOK, "%s", "pong")
})
// swagger:route POST /ping ping postPing
// summary: ping
// description: ping
// responses:
// default: default
// 200: ok
// 400: s400
// 500: s500
e.POST("/ping", func(context *gin.Context) {
context.String(http.StatusOK, "%s", "pong")
})
e.Run(":10100")
}
流程加强-3
如果用到jsonschema 去验证入参,需要使用 swagger:model 去完成
// swagger:model PutMemberDetailRequestPayload
type PutMemberDetailRequestPayload struct {
// ID is the organization id
// required: true
ID ID `uri:"id"`
// MemberID is the member id
// required: true
// minimum: 1
MemberID ID `json:"member_id" uri:"member_id"`
// required: true
*Member `json:",inline"`
}
// swagger:parameters updateMember
type PostMemberDetailRequestPayload struct {
// ID is the organization id
// in: path
// required: true
ID ID `json:"id" uri:"id"`
// This field is used only for validation
// required: true
// minimum: 1
// in: path
MemberID ID `json:"member_id" uri:"member_id"`
// in: body
Member *Member `json:",inline"`
}
-----------------------------------------------------------------------------------
被标注为swagger:parameters 的type 是无法 在`definitions` 下生成验证模型的,如果需要得定义个
别名,如下:
// swagger:model
type _ PostMemberDetailRequestPayload
生成文档
swagger generate spec -m -o ./swagger.json
-m 生成model 文档
{
"swagger": "2.0",
"paths": {},
"definitions": {
"PutMemberDetailRequestPayload": {
"description": "PutMemberDetailRequestPayload is put member detail request",
"type": "object",
"properties": {
"ID": {
"description": "ID is the organization id",
"type": "string"
},
"created_at": {
"description": "CreatedAt is the object creation time.",
"type": "string",
"format": "date-time",
"x-go-name": "CreatedAt"
},
"first_name": {
"description": "FirstName is the member first name",
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,32}$",
"x-go-name": "FirstName"
},
"id": {
"description": "ID is the unique identify to mark an object.",
"type": "string",
"minimum": 1,
"x-go-name": "ID"
},
"last_name": {
"description": "LastName is the member last name",
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,32}$",
"x-go-name": "LastName"
},
"member_id": {
"description": "MemberID is the member id",
"type": "string",
"x-go-name": "MemberID"
},
"org_id": {
"description": "OrgId indicates the organization where the member is in.",
"type": "string",
"x-go-name": "OrgId"
},
"role": {
"description": "Role indicates the role name of this member. It'll be used\nas the key of OrganizationRoleMap.",
"type": "string",
"pattern": "^[A-Za-z0-9-]{1,32}$",
"x-go-name": "Role"
},
"status": {
"description": "Status is the user status",
"type": "integer",
"format": "int64",
"x-go-name": "Status"
},
"updated_at": {
"description": "UpdatedAt is the last modified time of this object.",
"type": "string",
"format": "date-time",
"x-go-name": "UpdatedAt"
},
"user_id": {
"description": "UserId refers to an user, since an 3rd party User Management\nService might be used so the type is not uint64.",
"type": "string",
"x-go-name": "UserId"
}
},
"x-go-package": "github.com/api7/cloud/pkg/types"
}
},
"responses": {
}
}
此时,我们加载json 拿到definitions.PutMemberDetailRequestPayload 就可以用jsonschema验证入参了