文档:https://goswagger.io/

go-swagger 规范

  1. // swagger:operation PUT /api/v1/addr/update/{id} addr del
  2. // summary: 修改用户地址
  3. // description: 修改指定用户的addr
  4. // parameters:
  5. // - name: token
  6. // in: header
  7. // description: token
  8. // type: string
  9. // required: true
  10. // - name: id
  11. // in: path
  12. // description: 地址id
  13. // type: string
  14. // required: true
  15. // - name: addr
  16. // in: body
  17. // description: addr
  18. // type: string
  19. // required: true
  20. // responses:
  21. // 200: repoResp
  22. // 400: badReq
  1. // swagger:operaion [请求方式(可以是GET\PUT\DELETE\POST\PATCH)] [url:请求地址] [tag] [operation id] (同一标签的属于同一类,)
  2. // summary: 标题
  3. // description: 描述
  4. // parametres: 下面是参数了
  5. // - name: 参数名
  6. in: [header|body|query|path] 参数的位置
  7. description: 描述
  8. type: 类型
  9. required: 是否必须
  10. // responses: 响应
  11. // 200:
  12. // 404:

走通流程

  1. package main
  2. import (
  3. "net/http"
  4. "github.com/gin-contrib/cors"
  5. "github.com/gin-gonic/gin"
  6. )
  7. func main() {
  8. e := gin.Default()
  9. e.Use(cors.Default())
  10. // swagger:route GET /ping tag ping
  11. // summary: ping
  12. // description: ping
  13. // responses:
  14. // default: default
  15. // 200: ok
  16. // 400: s400
  17. // 500: s500
  18. e.GET("/ping", func(context *gin.Context) {
  19. context.String(http.StatusOK, "%s", "pong")
  20. })
  21. e.Run(":10100")
  22. }

使用

  1. 进入项目根目录
  2. swagger generate spec -o ./swagger.json // 根据swagger规范 创建 swagger.json 规范文档
  3. swagger serve -F=swagger swagger.json // 启动一个http服务

image.png
image.png
在该页面中,可以尝试做请求,不过可以看到,这里的 host 指向是错的,这里后面会提到

generation rule

swagger:meta

meta注释将一个文件标记为API元数据的源文件

  1. // version: 1.0.0
  2. // schemas: http, https
  3. // basePath: /
  4. // host: 127.0.0.1:10100
  5. // securityDefinitions:
  6. // cookie_header:
  7. // type: apiKey
  8. // name: Cookie
  9. // in: header
  10. // security:
  11. // - cookie_header:
  12. //
  13. // consumes: # 发送的类型
  14. // - application/json
  15. // produces: # 接收的类型
  16. // - application/json
  17. // License:
  18. // name: xxx
  19. // url: xxx
  20. // Contact:
  21. // name: API Support
  22. // url: http://www.swagger.io/support
  23. // email: support@swagger.io
  24. // swagger:meta
  25. package classification

swagger:model

  • Syntax swagger:model [?model name]

    1. // swagger:model
    2. type User struct {
    3. // the id for this user
    4. //
    5. // required: true
    6. // min: 1
    7. ID int64 `json:"id"`
    8. // the name for this user
    9. // required: true
    10. // min length: 3
    11. Name string `json:"name"`
    12. // the email address for this user
    13. //
    14. // required: true
    15. // example: user@provider.net
    16. Email strfmt.Email `json:"login"`
    17. // the friends for this user
    18. Friends []User `json:"friends"`
    19. }

swagger:parameters

  • Syntax swagger:parameters [operationid1 operationid2]
    1. // swagger:parameters postPing
    2. type Consumer struct {
    3. // Name of the consumer, should be unique among all applications in the same control plane.
    4. // required: true
    5. // example: jack
    6. // min length: 1
    7. // max length: 100
    8. // pattern: ^[a-zA-Z0-9_]+$
    9. // in: body
    10. Name string `json:"name"`
    11. // Description for this consumer.
    12. // min length: 1
    13. // max length: 256
    14. // example: jack is the most important API consumer.
    15. // in: body
    16. Description string `json:"description,omitempty"`
    17. }

流程加强-1

上面有提到,swagger-ui 中 请求的url指向不对,这时,我们可以通过 swagger:meta解决

  1. // version: 1.0.0
  2. // schemas: https
  3. // basePath: /
  4. // host: 127.0.0.1:10100
  5. // securityDefinitions:
  6. // cookie_header:
  7. // type: apiKey
  8. // name: Cookie
  9. // in: header
  10. // security:
  11. // - cookie_header:
  12. //
  13. // consumes:
  14. // - application/json
  15. // produces:
  16. // - application/json
  17. //
  18. // swagger:meta
  19. package main
  20. import (
  21. "net/http"
  22. "github.com/gin-contrib/cors"
  23. "github.com/gin-gonic/gin"
  24. )
  25. func main() {
  26. e := gin.Default()
  27. e.Use(cors.Default())
  28. // swagger:route GET /ping tag ping
  29. // summary: ping
  30. // description: ping
  31. // responses:
  32. // default: default
  33. // 200: ok
  34. // 400: s400
  35. // 500: s500
  36. e.GET("/ping", func(context *gin.Context) {
  37. context.String(http.StatusOK, "%s", "pong")
  38. })
  39. e.Run(":10100")
  40. }

image.png

流程加强-2

当请求参数比较复杂时,如何在swagger 中给出相应的提示?使用swagger:parameters

  1. // version: 1.0.0
  2. // schemas: https
  3. // basePath: /
  4. // host: 127.0.0.1:10100
  5. // securityDefinitions:
  6. // cookie_header:
  7. // type: apiKey
  8. // name: Cookie
  9. // in: header
  10. // security:
  11. // - cookie_header:
  12. //
  13. // consumes:
  14. // - application/json
  15. // produces:
  16. // - application/json
  17. //
  18. // swagger:meta
  19. package main
  20. import (
  21. "net/http"
  22. "github.com/gin-contrib/cors"
  23. "github.com/gin-gonic/gin"
  24. )
  25. // swagger:parameters postPing (如果有多个请求都用到了该结构,多个operationID 用空格分开)
  26. type Consumer struct {
  27. // Name of the consumer, should be unique among all applications in the same control plane.
  28. // required: true
  29. // example: jack
  30. // min length: 1
  31. // max length: 100
  32. // pattern: ^[a-zA-Z0-9_]+$
  33. // in: body
  34. Name string `json:"name"`
  35. // Description for this consumer.
  36. // min length: 1
  37. // max length: 256
  38. // example: jack is the most important API consumer.
  39. // in: body
  40. Description string `json:"description,omitempty"`
  41. // required: true
  42. // in: body
  43. C1 Consumer1
  44. }
  45. type Consumer1 struct {
  46. // in: body
  47. A string
  48. // in: body
  49. B string
  50. }
  51. func main() {
  52. e := gin.Default()
  53. e.Use(cors.Default())
  54. // swagger:route GET /ping ping getPing
  55. // summary: ping
  56. // description: ping
  57. // responses:
  58. // default: default
  59. // 200: ok
  60. // 400: s400
  61. // 500: s500
  62. e.GET("/ping", func(context *gin.Context) {
  63. var model Consumer
  64. if err := context.BindJSON(&model); err != nil {
  65. context.AbortWithStatusJSON(http.StatusBadRequest, "params error")
  66. return
  67. }
  68. context.String(http.StatusOK, "%s", "pong")
  69. })
  70. // swagger:route POST /ping ping postPing
  71. // summary: ping
  72. // description: ping
  73. // responses:
  74. // default: default
  75. // 200: ok
  76. // 400: s400
  77. // 500: s500
  78. e.POST("/ping", func(context *gin.Context) {
  79. context.String(http.StatusOK, "%s", "pong")
  80. })
  81. e.Run(":10100")
  82. }

image.png

流程加强-3

如果用到jsonschema 去验证入参,需要使用 swagger:model 去完成

  1. // swagger:model PutMemberDetailRequestPayload
  2. type PutMemberDetailRequestPayload struct {
  3. // ID is the organization id
  4. // required: true
  5. ID ID `uri:"id"`
  6. // MemberID is the member id
  7. // required: true
  8. // minimum: 1
  9. MemberID ID `json:"member_id" uri:"member_id"`
  10. // required: true
  11. *Member `json:",inline"`
  12. }
  13. // swagger:parameters updateMember
  14. type PostMemberDetailRequestPayload struct {
  15. // ID is the organization id
  16. // in: path
  17. // required: true
  18. ID ID `json:"id" uri:"id"`
  19. // This field is used only for validation
  20. // required: true
  21. // minimum: 1
  22. // in: path
  23. MemberID ID `json:"member_id" uri:"member_id"`
  24. // in: body
  25. Member *Member `json:",inline"`
  26. }
  27. -----------------------------------------------------------------------------------
  28. 被标注为swagger:parameters type 是无法 `definitions` 下生成验证模型的,如果需要得定义个
  29. 别名,如下:
  30. // swagger:model
  31. type _ PostMemberDetailRequestPayload

生成文档

  1. swagger generate spec -m -o ./swagger.json
  2. -m 生成model 文档
  1. {
  2. "swagger": "2.0",
  3. "paths": {},
  4. "definitions": {
  5. "PutMemberDetailRequestPayload": {
  6. "description": "PutMemberDetailRequestPayload is put member detail request",
  7. "type": "object",
  8. "properties": {
  9. "ID": {
  10. "description": "ID is the organization id",
  11. "type": "string"
  12. },
  13. "created_at": {
  14. "description": "CreatedAt is the object creation time.",
  15. "type": "string",
  16. "format": "date-time",
  17. "x-go-name": "CreatedAt"
  18. },
  19. "first_name": {
  20. "description": "FirstName is the member first name",
  21. "type": "string",
  22. "pattern": "^[A-Za-z0-9-]{1,32}$",
  23. "x-go-name": "FirstName"
  24. },
  25. "id": {
  26. "description": "ID is the unique identify to mark an object.",
  27. "type": "string",
  28. "minimum": 1,
  29. "x-go-name": "ID"
  30. },
  31. "last_name": {
  32. "description": "LastName is the member last name",
  33. "type": "string",
  34. "pattern": "^[A-Za-z0-9-]{1,32}$",
  35. "x-go-name": "LastName"
  36. },
  37. "member_id": {
  38. "description": "MemberID is the member id",
  39. "type": "string",
  40. "x-go-name": "MemberID"
  41. },
  42. "org_id": {
  43. "description": "OrgId indicates the organization where the member is in.",
  44. "type": "string",
  45. "x-go-name": "OrgId"
  46. },
  47. "role": {
  48. "description": "Role indicates the role name of this member. It'll be used\nas the key of OrganizationRoleMap.",
  49. "type": "string",
  50. "pattern": "^[A-Za-z0-9-]{1,32}$",
  51. "x-go-name": "Role"
  52. },
  53. "status": {
  54. "description": "Status is the user status",
  55. "type": "integer",
  56. "format": "int64",
  57. "x-go-name": "Status"
  58. },
  59. "updated_at": {
  60. "description": "UpdatedAt is the last modified time of this object.",
  61. "type": "string",
  62. "format": "date-time",
  63. "x-go-name": "UpdatedAt"
  64. },
  65. "user_id": {
  66. "description": "UserId refers to an user, since an 3rd party User Management\nService might be used so the type is not uint64.",
  67. "type": "string",
  68. "x-go-name": "UserId"
  69. }
  70. },
  71. "x-go-package": "github.com/api7/cloud/pkg/types"
  72. }
  73. },
  74. "responses": {
  75. }
  76. }

此时,我们加载json 拿到definitions.PutMemberDetailRequestPayload 就可以用jsonschema验证入参了