From 38b5f15bd8f9729cb0ca28e886815e4311690a19 Mon Sep 17 00:00:00 2001 From: sdghchj Date: Fri, 28 Oct 2022 14:40:19 +0800 Subject: [PATCH] feat: make swagger comments more readable for go doc (#1366) * make swagger comments more readable for go doc Signed-off-by: sdghchj * fix unit tests Signed-off-by: sdghchj * update examples Signed-off-by: sdghchj * update examples Signed-off-by: sdghchj Signed-off-by: sdghchj --- example/basic/api/api.go | 72 ++++---- example/basic/main.go | 23 +-- example/celler/controller/accounts.go | 142 +++++++-------- example/celler/controller/admin.go | 25 +-- example/celler/controller/bottles.go | 46 ++--- example/celler/controller/examples.go | 171 ++++++++++--------- example/celler/main.go | 84 ++++----- example/go-module-support/main.go | 23 +-- example/markdown/api/api.go | 70 ++++---- example/markdown/main.go | 26 +-- example/object-map-example/controller/api.go | 15 +- example/object-map-example/main.go | 15 +- example/override/handler.go | 13 +- example/override/main.go | 23 +-- formatter.go | 4 +- formatter_test.go | 132 +++++++------- 16 files changed, 457 insertions(+), 427 deletions(-) diff --git a/example/basic/api/api.go b/example/basic/api/api.go index 52be29cd5..06f4882e2 100644 --- a/example/basic/api/api.go +++ b/example/basic/api/api.go @@ -8,17 +8,18 @@ import ( ) // GetStringByInt example -// @Summary Add a new pet to the store -// @Description get string by ID -// @ID get-string-by-int -// @Accept json -// @Produce json -// @Param some_id path int true "Some ID" -// @Param some_id body web.Pet true "Some ID" -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 404 {object} web.APIError "Can not find ID" -// @Router /testapi/get-string-by-int/{some_id} [get] +// +// @Summary Add a new pet to the store +// @Description get string by ID +// @ID get-string-by-int +// @Accept json +// @Produce json +// @Param some_id path int true "Some ID" +// @Param some_id body web.Pet true "Some ID" +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 404 {object} web.APIError "Can not find ID" +// @Router /testapi/get-string-by-int/{some_id} [get] func GetStringByInt(w http.ResponseWriter, r *http.Request) { var pet web.Pet if err := json.NewDecoder(r.Body).Decode(&pet); err != nil { @@ -30,39 +31,42 @@ func GetStringByInt(w http.ResponseWriter, r *http.Request) { } // GetStructArrayByString example -// @Description get struct array by ID -// @ID get-struct-array-by-string -// @Accept json -// @Produce json -// @Param some_id path string true "Some ID" -// @Param offset query int true "Offset" -// @Param limit query int true "Offset" -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 404 {object} web.APIError "Can not find ID" -// @Router /testapi/get-struct-array-by-string/{some_id} [get] +// +// @Description get struct array by ID +// @ID get-struct-array-by-string +// @Accept json +// @Produce json +// @Param some_id path string true "Some ID" +// @Param offset query int true "Offset" +// @Param limit query int true "Offset" +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 404 {object} web.APIError "Can not find ID" +// @Router /testapi/get-struct-array-by-string/{some_id} [get] func GetStructArrayByString(w http.ResponseWriter, r *http.Request) { // write your code } // Upload example -// @Summary Upload file -// @Description Upload file -// @ID file.upload -// @Accept multipart/form-data -// @Produce json -// @Param file formData file true "this is a test file" -// @Success 200 {string} string "ok" -// @Failure 400 {object} web.APIError "We need ID!!" -// @Failure 404 {object} web.APIError "Can not find ID" -// @Router /file/upload [post] +// +// @Summary Upload file +// @Description Upload file +// @ID file.upload +// @Accept multipart/form-data +// @Produce json +// @Param file formData file true "this is a test file" +// @Success 200 {string} string "ok" +// @Failure 400 {object} web.APIError "We need ID!!" +// @Failure 404 {object} web.APIError "Can not find ID" +// @Router /file/upload [post] func Upload(w http.ResponseWriter, r *http.Request) { // write your code } // AnonymousField example -// @Summary use Anonymous field -// @Success 200 {object} web.RevValue "ok" +// +// @Summary use Anonymous field +// @Success 200 {object} web.RevValue "ok" func AnonymousField() { } diff --git a/example/basic/main.go b/example/basic/main.go index 9f22eb586..e0a5d94fa 100644 --- a/example/basic/main.go +++ b/example/basic/main.go @@ -6,20 +6,21 @@ import ( "github.com/swaggo/swag/example/basic/api" ) -// @title Swagger Example API -// @version 1.0 -// @description This is a sample server Petstore server. -// @termsOfService http://swagger.io/terms/ +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server Petstore server. +// @termsOfService http://swagger.io/terms/ -// @contact.name API Support -// @contact.url http://www.swagger.io/support -// @contact.email support@swagger.io +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host petstore.swagger.io +// @BasePath /v2 -// @host petstore.swagger.io -// @BasePath /v2 func main() { http.HandleFunc("/testapi/get-string-by-int/", api.GetStringByInt) http.HandleFunc("//testapi/get-struct-array-by-string/", api.GetStructArrayByString) diff --git a/example/celler/controller/accounts.go b/example/celler/controller/accounts.go index e52ec81ec..f09698f4d 100644 --- a/example/celler/controller/accounts.go +++ b/example/celler/controller/accounts.go @@ -11,17 +11,18 @@ import ( ) // ShowAccount godoc -// @Summary Show an account -// @Description get string by ID -// @Tags accounts -// @Accept json -// @Produce json -// @Param id path int true "Account ID" -// @Success 200 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id} [get] +// +// @Summary Show an account +// @Description get string by ID +// @Tags accounts +// @Accept json +// @Produce json +// @Param id path int true "Account ID" +// @Success 200 {object} model.Account +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /accounts/{id} [get] func (c *Controller) ShowAccount(ctx *gin.Context) { id := ctx.Param("id") aid, err := strconv.Atoi(id) @@ -38,17 +39,18 @@ func (c *Controller) ShowAccount(ctx *gin.Context) { } // ListAccounts godoc -// @Summary List accounts -// @Description get accounts -// @Tags accounts -// @Accept json -// @Produce json -// @Param q query string false "name search by q" Format(email) -// @Success 200 {array} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts [get] +// +// @Summary List accounts +// @Description get accounts +// @Tags accounts +// @Accept json +// @Produce json +// @Param q query string false "name search by q" Format(email) +// @Success 200 {array} model.Account +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /accounts [get] func (c *Controller) ListAccounts(ctx *gin.Context) { q := ctx.Request.URL.Query().Get("q") accounts, err := model.AccountsAll(q) @@ -60,17 +62,18 @@ func (c *Controller) ListAccounts(ctx *gin.Context) { } // AddAccount godoc -// @Summary Add an account -// @Description add by json account -// @Tags accounts -// @Accept json -// @Produce json -// @Param account body model.AddAccount true "Add account" -// @Success 200 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts [post] +// +// @Summary Add an account +// @Description add by json account +// @Tags accounts +// @Accept json +// @Produce json +// @Param account body model.AddAccount true "Add account" +// @Success 200 {object} model.Account +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /accounts [post] func (c *Controller) AddAccount(ctx *gin.Context) { var addAccount model.AddAccount if err := ctx.ShouldBindJSON(&addAccount); err != nil { @@ -94,18 +97,19 @@ func (c *Controller) AddAccount(ctx *gin.Context) { } // UpdateAccount godoc -// @Summary Update an account -// @Description Update by json account -// @Tags accounts -// @Accept json -// @Produce json -// @Param id path int true "Account ID" -// @Param account body model.UpdateAccount true "Update account" -// @Success 200 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id} [patch] +// +// @Summary Update an account +// @Description Update by json account +// @Tags accounts +// @Accept json +// @Produce json +// @Param id path int true "Account ID" +// @Param account body model.UpdateAccount true "Update account" +// @Success 200 {object} model.Account +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /accounts/{id} [patch] func (c *Controller) UpdateAccount(ctx *gin.Context) { id := ctx.Param("id") aid, err := strconv.Atoi(id) @@ -131,17 +135,18 @@ func (c *Controller) UpdateAccount(ctx *gin.Context) { } // DeleteAccount godoc -// @Summary Delete an account -// @Description Delete by account ID -// @Tags accounts -// @Accept json -// @Produce json -// @Param id path int true "Account ID" Format(int64) -// @Success 204 {object} model.Account -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id} [delete] +// +// @Summary Delete an account +// @Description Delete by account ID +// @Tags accounts +// @Accept json +// @Produce json +// @Param id path int true "Account ID" Format(int64) +// @Success 204 {object} model.Account +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /accounts/{id} [delete] func (c *Controller) DeleteAccount(ctx *gin.Context) { id := ctx.Param("id") aid, err := strconv.Atoi(id) @@ -158,18 +163,19 @@ func (c *Controller) DeleteAccount(ctx *gin.Context) { } // UploadAccountImage godoc -// @Summary Upload account image -// @Description Upload file -// @Tags accounts -// @Accept multipart/form-data -// @Produce json -// @Param id path int true "Account ID" -// @Param file formData file true "account image" -// @Success 200 {object} controller.Message -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /accounts/{id}/images [post] +// +// @Summary Upload account image +// @Description Upload file +// @Tags accounts +// @Accept multipart/form-data +// @Produce json +// @Param id path int true "Account ID" +// @Param file formData file true "account image" +// @Success 200 {object} controller.Message +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /accounts/{id}/images [post] func (c *Controller) UploadAccountImage(ctx *gin.Context) { id, err := strconv.Atoi(ctx.Param("id")) if err != nil { diff --git a/example/celler/controller/admin.go b/example/celler/controller/admin.go index 65f16b2b7..5eecffd47 100644 --- a/example/celler/controller/admin.go +++ b/example/celler/controller/admin.go @@ -11,18 +11,19 @@ import ( ) // Auth godoc -// @Summary Auth admin -// @Description get admin info -// @Tags accounts,admin -// @Accept json -// @Produce json -// @Success 200 {object} model.Admin -// @Failure 400 {object} httputil.HTTPError -// @Failure 401 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Security ApiKeyAuth -// @Router /admin/auth [post] +// +// @Summary Auth admin +// @Description get admin info +// @Tags accounts,admin +// @Accept json +// @Produce json +// @Success 200 {object} model.Admin +// @Failure 400 {object} httputil.HTTPError +// @Failure 401 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Security ApiKeyAuth +// @Router /admin/auth [post] func (c *Controller) Auth(ctx *gin.Context) { authHeader := ctx.GetHeader("Authorization") if len(authHeader) == 0 { diff --git a/example/celler/controller/bottles.go b/example/celler/controller/bottles.go index 4f35ee5cf..6dc75bfca 100644 --- a/example/celler/controller/bottles.go +++ b/example/celler/controller/bottles.go @@ -11,18 +11,19 @@ import ( ) // ShowBottle godoc -// @Summary Show a bottle -// @Description get string by ID -// @ID get-string-by-int -// @Tags bottles -// @Accept json -// @Produce json -// @Param id path int true "Bottle ID" -// @Success 200 {object} model.Bottle -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /bottles/{id} [get] +// +// @Summary Show a bottle +// @Description get string by ID +// @ID get-string-by-int +// @Tags bottles +// @Accept json +// @Produce json +// @Param id path int true "Bottle ID" +// @Success 200 {object} model.Bottle +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /bottles/{id} [get] func (c *Controller) ShowBottle(ctx *gin.Context) { id := ctx.Param("id") bid, err := strconv.Atoi(id) @@ -39,16 +40,17 @@ func (c *Controller) ShowBottle(ctx *gin.Context) { } // ListBottles godoc -// @Summary List bottles -// @Description get bottles -// @Tags bottles -// @Accept json -// @Produce json -// @Success 200 {array} model.Bottle -// @Failure 400 {object} httputil.HTTPError -// @Failure 404 {object} httputil.HTTPError -// @Failure 500 {object} httputil.HTTPError -// @Router /bottles [get] +// +// @Summary List bottles +// @Description get bottles +// @Tags bottles +// @Accept json +// @Produce json +// @Success 200 {array} model.Bottle +// @Failure 400 {object} httputil.HTTPError +// @Failure 404 {object} httputil.HTTPError +// @Failure 500 {object} httputil.HTTPError +// @Router /bottles [get] func (c *Controller) ListBottles(ctx *gin.Context) { bottles, err := model.BottlesAll() if err != nil { diff --git a/example/celler/controller/examples.go b/example/celler/controller/examples.go index 8118d7f0d..3deff41f6 100644 --- a/example/celler/controller/examples.go +++ b/example/celler/controller/examples.go @@ -10,33 +10,35 @@ import ( ) // PingExample godoc -// @Summary ping example -// @Description do ping -// @Tags example -// @Accept json -// @Produce plain -// @Success 200 {string} string "pong" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/ping [get] +// +// @Summary ping example +// @Description do ping +// @Tags example +// @Accept json +// @Produce plain +// @Success 200 {string} string "pong" +// @Failure 400 {string} string "ok" +// @Failure 404 {string} string "ok" +// @Failure 500 {string} string "ok" +// @Router /examples/ping [get] func (c *Controller) PingExample(ctx *gin.Context) { ctx.String(http.StatusOK, "pong") } // CalcExample godoc -// @Summary calc example -// @Description plus -// @Tags example -// @Accept json -// @Produce plain -// @Param val1 query int true "used for calc" -// @Param val2 query int true "used for calc" -// @Success 200 {integer} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/calc [get] +// +// @Summary calc example +// @Description plus +// @Tags example +// @Accept json +// @Produce plain +// @Param val1 query int true "used for calc" +// @Param val2 query int true "used for calc" +// @Success 200 {integer} string "answer" +// @Failure 400 {string} string "ok" +// @Failure 404 {string} string "ok" +// @Failure 500 {string} string "ok" +// @Router /examples/calc [get] func (c *Controller) CalcExample(ctx *gin.Context) { val1, err := strconv.Atoi(ctx.Query("val1")) if err != nil { @@ -53,18 +55,19 @@ func (c *Controller) CalcExample(ctx *gin.Context) { } // PathParamsExample godoc -// @Summary path params example -// @Description path params -// @Tags example -// @Accept json -// @Produce plain -// @Param group_id path int true "Group ID" -// @Param account_id path int true "Account ID" -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/groups/{group_id}/accounts/{account_id} [get] +// +// @Summary path params example +// @Description path params +// @Tags example +// @Accept json +// @Produce plain +// @Param group_id path int true "Group ID" +// @Param account_id path int true "Account ID" +// @Success 200 {string} string "answer" +// @Failure 400 {string} string "ok" +// @Failure 404 {string} string "ok" +// @Failure 500 {string} string "ok" +// @Router /examples/groups/{group_id}/accounts/{account_id} [get] func (c *Controller) PathParamsExample(ctx *gin.Context) { groupID, err := strconv.Atoi(ctx.Param("group_id")) if err != nil { @@ -80,55 +83,58 @@ func (c *Controller) PathParamsExample(ctx *gin.Context) { } // HeaderExample godoc -// @Summary custome header example -// @Description custome header -// @Tags example -// @Accept json -// @Produce plain -// @Param Authorization header string true "Authentication header" -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/header [get] +// +// @Summary custome header example +// @Description custome header +// @Tags example +// @Accept json +// @Produce plain +// @Param Authorization header string true "Authentication header" +// @Success 200 {string} string "answer" +// @Failure 400 {string} string "ok" +// @Failure 404 {string} string "ok" +// @Failure 500 {string} string "ok" +// @Router /examples/header [get] func (c *Controller) HeaderExample(ctx *gin.Context) { ctx.String(http.StatusOK, ctx.GetHeader("Authorization")) } // SecuritiesExample godoc -// @Summary custome header example -// @Description custome header -// @Tags example -// @Accept json -// @Produce json -// @Param Authorization header string true "Authentication header" -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Security ApiKeyAuth -// @Security OAuth2Implicit[admin, write] -// @Router /examples/securities [get] +// +// @Summary custome header example +// @Description custome header +// @Tags example +// @Accept json +// @Produce json +// @Param Authorization header string true "Authentication header" +// @Success 200 {string} string "answer" +// @Failure 400 {string} string "ok" +// @Failure 404 {string} string "ok" +// @Failure 500 {string} string "ok" +// @Security ApiKeyAuth +// @Security OAuth2Implicit[admin, write] +// @Router /examples/securities [get] func (c *Controller) SecuritiesExample(ctx *gin.Context) { } // AttributeExample godoc -// @Summary attribute example -// @Description attribute -// @Tags example -// @Accept json -// @Produce plain -// @Param enumstring query string false "string enums" Enums(A, B, C) -// @Param enumint query int false "int enums" Enums(1, 2, 3) -// @Param enumnumber query number false "int enums" Enums(1.1, 1.2, 1.3) -// @Param string query string false "string valid" minlength(5) maxlength(10) -// @Param int query int false "int valid" minimum(1) maximum(10) -// @Param default query string false "string default" default(A) -// @Success 200 {string} string "answer" -// @Failure 400 {string} string "ok" -// @Failure 404 {string} string "ok" -// @Failure 500 {string} string "ok" -// @Router /examples/attribute [get] +// +// @Summary attribute example +// @Description attribute +// @Tags example +// @Accept json +// @Produce plain +// @Param enumstring query string false "string enums" Enums(A, B, C) +// @Param enumint query int false "int enums" Enums(1, 2, 3) +// @Param enumnumber query number false "int enums" Enums(1.1, 1.2, 1.3) +// @Param string query string false "string valid" minlength(5) maxlength(10) +// @Param int query int false "int valid" minimum(1) maximum(10) +// @Param default query string false "string default" default(A) +// @Success 200 {string} string "answer" +// @Failure 400 {string} string "ok" +// @Failure 404 {string} string "ok" +// @Failure 500 {string} string "ok" +// @Router /examples/attribute [get] func (c *Controller) AttributeExample(ctx *gin.Context) { ctx.String(http.StatusOK, fmt.Sprintf("enumstring=%s enumint=%s enumnumber=%s string=%s int=%s default=%s", ctx.Query("enumstring"), @@ -141,13 +147,14 @@ func (c *Controller) AttributeExample(ctx *gin.Context) { } // PostExample godoc -// @Summary post request example -// @Description post request example -// @Accept json -// @Produce plain -// @Param message body model.Account true "Account Info" -// @Success 200 {string} string "success" -// @Failure 500 {string} string "fail" -// @Router /examples/post [post] +// +// @Summary post request example +// @Description post request example +// @Accept json +// @Produce plain +// @Param message body model.Account true "Account Info" +// @Success 200 {string} string "success" +// @Failure 500 {string} string "fail" +// @Router /examples/post [post] func (c *Controller) PostExample(ctx *gin.Context) { } diff --git a/example/celler/main.go b/example/celler/main.go index 87d4742a4..8f247b3d7 100644 --- a/example/celler/main.go +++ b/example/celler/main.go @@ -13,48 +13,48 @@ import ( ginSwagger "github.com/swaggo/gin-swagger" ) -// @title Swagger Example API -// @version 1.0 -// @description This is a sample server celler server. -// @termsOfService http://swagger.io/terms/ - -// @contact.name API Support -// @contact.url http://www.swagger.io/support -// @contact.email support@swagger.io - -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html - -// @host localhost:8080 -// @BasePath /api/v1 - -// @securityDefinitions.basic BasicAuth - -// @securityDefinitions.apikey ApiKeyAuth -// @in header -// @name Authorization -// @description Description for what is this security definition being used - -// @securitydefinitions.oauth2.application OAuth2Application -// @tokenUrl https://example.com/oauth/token -// @scope.write Grants write access -// @scope.admin Grants read and write access to administrative information - -// @securitydefinitions.oauth2.implicit OAuth2Implicit -// @authorizationUrl https://example.com/oauth/authorize -// @scope.write Grants write access -// @scope.admin Grants read and write access to administrative information - -// @securitydefinitions.oauth2.password OAuth2Password -// @tokenUrl https://example.com/oauth/token -// @scope.read Grants read access -// @scope.write Grants write access -// @scope.admin Grants read and write access to administrative information - -// @securitydefinitions.oauth2.accessCode OAuth2AccessCode -// @tokenUrl https://example.com/oauth/token -// @authorizationUrl https://example.com/oauth/authorize -// @scope.admin Grants read and write access to administrative information +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server celler server. +// @termsOfService http://swagger.io/terms/ + +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io + +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host localhost:8080 +// @BasePath /api/v1 + +// @securityDefinitions.basic BasicAuth + +// @securityDefinitions.apikey ApiKeyAuth +// @in header +// @name Authorization +// @description Description for what is this security definition being used + +// @securitydefinitions.oauth2.application OAuth2Application +// @tokenUrl https://example.com/oauth/token +// @scope.write Grants write access +// @scope.admin Grants read and write access to administrative information + +// @securitydefinitions.oauth2.implicit OAuth2Implicit +// @authorizationUrl https://example.com/oauth/authorize +// @scope.write Grants write access +// @scope.admin Grants read and write access to administrative information + +// @securitydefinitions.oauth2.password OAuth2Password +// @tokenUrl https://example.com/oauth/token +// @scope.read Grants read access +// @scope.write Grants write access +// @scope.admin Grants read and write access to administrative information + +// @securitydefinitions.oauth2.accessCode OAuth2AccessCode +// @tokenUrl https://example.com/oauth/token +// @authorizationUrl https://example.com/oauth/authorize +// @scope.admin Grants read and write access to administrative information func main() { r := gin.Default() diff --git a/example/go-module-support/main.go b/example/go-module-support/main.go index 40d29d749..45b66a801 100644 --- a/example/go-module-support/main.go +++ b/example/go-module-support/main.go @@ -5,20 +5,21 @@ import ( "github.com/swaggo/examples/go-module-support/api" // included package from external ) -// @title Swagger Example API -// @version 1.0 -// @description This is a sample server Petstore server. -// @termsOfService http://swagger.io/terms/ +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server Petstore server. +// @termsOfService http://swagger.io/terms/ -// @contact.name API Support -// @contact.url http://www.swagger.io/support -// @contact.email support@swagger.io +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host petstore.swagger.io +// @BasePath /v2 -// @host petstore.swagger.io -// @BasePath /v2 func main() { r := gin.New() r.GET("/testapi/get-string-by-int/:some_id", api.GetStringByInt) diff --git a/example/markdown/api/api.go b/example/markdown/api/api.go index 578271da8..a6905eefe 100644 --- a/example/markdown/api/api.go +++ b/example/markdown/api/api.go @@ -23,54 +23,58 @@ type APIError struct { } // ListUsers example -// @Summary List users from the store -// @Tags admin -// @Accept json -// @Produce json -// @Success 200 {array} api.UsersCollection "ok" -// @Router /admin/user/ [get] +// +// @Summary List users from the store +// @Tags admin +// @Accept json +// @Produce json +// @Success 200 {array} api.UsersCollection "ok" +// @Router /admin/user/ [get] func ListUsers(w http.ResponseWriter, r *http.Request) { // write your code } // GetUser example -// @Summary Read user from the store -// @Tags admin -// @Accept json -// @Produce json -// @Param id path int true "User Id" -// @Success 200 {object} api.User -// @Failure 400 {object} api.APIError "We need ID!!" -// @Failure 404 {object} api.APIError "Can not find ID" -// @Router /admin/user/{id} [get] +// +// @Summary Read user from the store +// @Tags admin +// @Accept json +// @Produce json +// @Param id path int true "User Id" +// @Success 200 {object} api.User +// @Failure 400 {object} api.APIError "We need ID!!" +// @Failure 404 {object} api.APIError "Can not find ID" +// @Router /admin/user/{id} [get] func GetUser(w http.ResponseWriter, r *http.Request) { // write your code } // AddUser example -// @Summary Add a new user to the store -// @Tags admin -// @Accept json -// @Produce json -// @Param message body api.User true "User Data" -// @Success 200 {string} string "ok" -// @Failure 400 {object} api.APIError "We need ID!!" -// @Failure 404 {object} api.APIError "Can not find ID" -// @Router /admin/user/ [post] +// +// @Summary Add a new user to the store +// @Tags admin +// @Accept json +// @Produce json +// @Param message body api.User true "User Data" +// @Success 200 {string} string "ok" +// @Failure 400 {object} api.APIError "We need ID!!" +// @Failure 404 {object} api.APIError "Can not find ID" +// @Router /admin/user/ [post] func AddUser(w http.ResponseWriter, r *http.Request) { // write your code } // UpdateUser example -// @Summary Add a new user to the store -// @Tags admin -// @Accept json -// @Produce json -// @Param message body api.User true "User Data" -// @Success 200 {string} string "ok" -// @Failure 400 {object} api.APIError "We need ID!!" -// @Failure 404 {object} api.APIError "Can not find ID" -// @Router /admin/user/ [put] +// +// @Summary Add a new user to the store +// @Tags admin +// @Accept json +// @Produce json +// @Param message body api.User true "User Data" +// @Success 200 {string} string "ok" +// @Failure 400 {object} api.APIError "We need ID!!" +// @Failure 404 {object} api.APIError "Can not find ID" +// @Router /admin/user/ [put] func UpdateUser(w http.ResponseWriter, r *http.Request) { // write your code } diff --git a/example/markdown/main.go b/example/markdown/main.go index bd2b97ae2..e2bb4d994 100644 --- a/example/markdown/main.go +++ b/example/markdown/main.go @@ -9,23 +9,23 @@ import ( _ "github.com/swaggo/swag/example/markdown/docs" ) -// @title Swagger Example API -// @version 1.0 -// @description This is a sample server Petstore server. -// @description.markdown -// @termsOfService http://swagger.io/terms/ +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server Petstore server. +// @description.markdown +// @termsOfService http://swagger.io/terms/ -// @contact.name API Support -// @contact.url http://www.swagger.io/support -// @contact.email support@swagger.io +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html -// @tag.name admin -// @tag.description.markdown +// @tag.name admin +// @tag.description.markdown -// @BasePath /v2 +// @BasePath /v2 func main() { router := mux.NewRouter() diff --git a/example/object-map-example/controller/api.go b/example/object-map-example/controller/api.go index 83b5e99fe..3e8f4b222 100644 --- a/example/object-map-example/controller/api.go +++ b/example/object-map-example/controller/api.go @@ -3,13 +3,14 @@ package controller import "github.com/gin-gonic/gin" // GetMap godoc -// @Summary Get Map Example -// @Description get map -// @ID get-map -// @Accept json -// @Produce json -// @Success 200 {object} Response -// @Router /test [get] +// +// @Summary Get Map Example +// @Description get map +// @ID get-map +// @Accept json +// @Produce json +// @Success 200 {object} Response +// @Router /test [get] func (c *Controller) GetMap(ctx *gin.Context) { ctx.JSON(200, Response{ Title: map[string]string{ diff --git a/example/object-map-example/main.go b/example/object-map-example/main.go index 0108f2c9f..002197a75 100644 --- a/example/object-map-example/main.go +++ b/example/object-map-example/main.go @@ -9,15 +9,16 @@ import ( ginSwagger "github.com/swaggo/gin-swagger" ) -// @title Swagger Map Example API -// @version 1.0 -// @termsOfService http://swagger.io/terms/ +// @title Swagger Map Example API +// @version 1.0 +// @termsOfService http://swagger.io/terms/ -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host localhost:8080 +// @BasePath /api/v1 -// @host localhost:8080 -// @BasePath /api/v1 func main() { r := gin.Default() diff --git a/example/override/handler.go b/example/override/handler.go index 4f9e67003..93cf7b2bd 100644 --- a/example/override/handler.go +++ b/example/override/handler.go @@ -13,12 +13,13 @@ type ProductUpdates struct { } // UpdateProduct example -// @Summary Update product attributes -// @ID update-product -// @Accept json -// @Param product_id path int true "Product ID" -// @Param _ body ProductUpdates true " " -// @Router /testapi/update-product/{product_id} [post] +// +// @Summary Update product attributes +// @ID update-product +// @Accept json +// @Param product_id path int true "Product ID" +// @Param _ body ProductUpdates true " " +// @Router /testapi/update-product/{product_id} [post] func UpdateProduct(w http.ResponseWriter, r *http.Request) { var pUpdates ProductUpdates if err := json.NewDecoder(r.Body).Decode(&pUpdates); err != nil { diff --git a/example/override/main.go b/example/override/main.go index c19711ea4..2f04faa7a 100644 --- a/example/override/main.go +++ b/example/override/main.go @@ -4,20 +4,21 @@ import ( "net/http" ) -// @title Swagger Example API -// @version 1.0 -// @description This is a sample server with null types overridden with primitive types. -// @termsOfService http://swagger.io/terms/ +// @title Swagger Example API +// @version 1.0 +// @description This is a sample server with null types overridden with primitive types. +// @termsOfService http://swagger.io/terms/ -// @contact.name API Support -// @contact.url http://www.swagger.io/support -// @contact.email support@swagger.io +// @contact.name API Support +// @contact.url http://www.swagger.io/support +// @contact.email support@swagger.io -// @license.name Apache 2.0 -// @license.url http://www.apache.org/licenses/LICENSE-2.0.html +// @license.name Apache 2.0 +// @license.url http://www.apache.org/licenses/LICENSE-2.0.html + +// @host product_info.swagger.io +// @BasePath /v2 -// @host product_info.swagger.io -// @BasePath /v2 func main() { http.HandleFunc("/testapi/update-product", UpdateProduct) http.ListenAndServe(":8080", nil) diff --git a/formatter.go b/formatter.go index c412fcc7f..be25c77c9 100644 --- a/formatter.go +++ b/formatter.go @@ -107,12 +107,12 @@ func formatFuncDoc(fileSet *token.FileSet, commentList []*ast.Comment, edits *ed linesToComments := make(map[int]int, len(commentList)) buffer := &bytes.Buffer{} - w := tabwriter.NewWriter(buffer, 0, 0, 1, ' ', 0) + w := tabwriter.NewWriter(buffer, 0, 0, 2, ' ', 0) for commentIndex, comment := range commentList { text := comment.Text if attr, body, found := swagComment(text); found { - formatted := "// " + attr + formatted := "//\t" + attr if body != "" { formatted += "\t" + splitComment2(attr, body) } diff --git a/formatter_test.go b/formatter_test.go index bc9134b31..d445df2d1 100644 --- a/formatter_test.go +++ b/formatter_test.go @@ -64,47 +64,47 @@ func Test_FormatMain(t *testing.T) { func main() {}` want := `package main - // @title Swagger Example API - // @version 1.0 - // @description This is a sample server Petstore server. - // @termsOfService http://swagger.io/terms/ - - // @contact.name API Support - // @contact.url http://www.swagger.io/support - // @contact.email support@swagger.io - - // @license.name Apache 2.0 - // @license.url http://www.apache.org/licenses/LICENSE-2.0.html - - // @host petstore.swagger.io - // @BasePath /v2 - - // @securityDefinitions.basic BasicAuth - - // @securityDefinitions.apikey ApiKeyAuth - // @in header - // @name Authorization - - // @securitydefinitions.oauth2.application OAuth2Application - // @tokenUrl https://example.com/oauth/token - // @scope.write Grants write access - // @scope.admin Grants read and write access to administrative information - - // @securitydefinitions.oauth2.implicit OAuth2Implicit - // @authorizationurl https://example.com/oauth/authorize - // @scope.write Grants write access - // @scope.admin Grants read and write access to administrative information - - // @securitydefinitions.oauth2.password OAuth2Password - // @tokenUrl https://example.com/oauth/token - // @scope.read Grants read access - // @scope.write Grants write access - // @scope.admin Grants read and write access to administrative information - - // @securitydefinitions.oauth2.accessCode OAuth2AccessCode - // @tokenUrl https://example.com/oauth/token - // @authorizationurl https://example.com/oauth/authorize - // @scope.admin Grants read and write access to administrative information + // @title Swagger Example API + // @version 1.0 + // @description This is a sample server Petstore server. + // @termsOfService http://swagger.io/terms/ + + // @contact.name API Support + // @contact.url http://www.swagger.io/support + // @contact.email support@swagger.io + + // @license.name Apache 2.0 + // @license.url http://www.apache.org/licenses/LICENSE-2.0.html + + // @host petstore.swagger.io + // @BasePath /v2 + + // @securityDefinitions.basic BasicAuth + + // @securityDefinitions.apikey ApiKeyAuth + // @in header + // @name Authorization + + // @securitydefinitions.oauth2.application OAuth2Application + // @tokenUrl https://example.com/oauth/token + // @scope.write Grants write access + // @scope.admin Grants read and write access to administrative information + + // @securitydefinitions.oauth2.implicit OAuth2Implicit + // @authorizationurl https://example.com/oauth/authorize + // @scope.write Grants write access + // @scope.admin Grants read and write access to administrative information + + // @securitydefinitions.oauth2.password OAuth2Password + // @tokenUrl https://example.com/oauth/token + // @scope.read Grants read access + // @scope.write Grants write access + // @scope.admin Grants read and write access to administrative information + + // @securitydefinitions.oauth2.accessCode OAuth2AccessCode + // @tokenUrl https://example.com/oauth/token + // @authorizationurl https://example.com/oauth/authorize + // @scope.admin Grants read and write access to administrative information func main() {}` testFormat(t, "main.go", contents, want) @@ -126,15 +126,15 @@ func Test_FormatMultipleFunctions(t *testing.T) { want := `package main - // @Produce json - // @Success 200 {object} string - // @Failure 400 {object} string + // @Produce json + // @Success 200 {object} string + // @Failure 400 {object} string func A() {} - // @Description Description of B. - // @Produce json - // @Success 200 {array} string - // @Failure 400 {object} string + // @Description Description of B. + // @Produce json + // @Success 200 {array} string + // @Failure 400 {object} string func B() {}` testFormat(t, "main.go", contents, want) @@ -162,17 +162,17 @@ func Test_FormatApi(t *testing.T) { import "net/http" - // @Summary Add a new pet to the store - // @Description get string by ID - // @ID get-string-by-int - // @Accept json - // @Produce json - // @Param some_id path int true "Some ID" Format(int64) - // @Param some_id body web.Pet true "Some ID" - // @Success 200 {string} string "ok" - // @Failure 400 {object} web.APIError "We need ID!!" - // @Failure 404 {object} web.APIError "Can not find ID" - // @Router /testapi/get-string-by-int/{some_id} [get] + // @Summary Add a new pet to the store + // @Description get string by ID + // @ID get-string-by-int + // @Accept json + // @Produce json + // @Param some_id path int true "Some ID" Format(int64) + // @Param some_id body web.Pet true "Some ID" + // @Success 200 {string} string "ok" + // @Failure 400 {object} web.APIError "We need ID!!" + // @Failure 404 {object} web.APIError "Can not find ID" + // @Router /testapi/get-string-by-int/{some_id} [get] func GetStringByInt(w http.ResponseWriter, r *http.Request) {}` testFormat(t, "api.go", contents, want) @@ -186,9 +186,9 @@ func Test_NonSwagComment(t *testing.T) { // @ Accept json // This is not a @swag comment` want := `package api - // @Summary Add a new pet to the store - // @Description get string by ID - // @ID get-string-by-int + // @Summary Add a new pet to the store + // @Description get string by ID + // @ID get-string-by-int // @ Accept json // This is not a @swag comment` @@ -200,8 +200,8 @@ func Test_EmptyComment(t *testing.T) { // @Summary Add a new pet to the store // @Description ` want := `package empty - // @Summary Add a new pet to the store - // @Description` + // @Summary Add a new pet to the store + // @Description` testFormat(t, "empty.go", contents, want) } @@ -211,8 +211,8 @@ func Test_AlignAttribute(t *testing.T) { // @Summary Add a new pet to the store // @Description Description` want := `package align - // @Summary Add a new pet to the store - // @Description Description` + // @Summary Add a new pet to the store + // @Description Description` testFormat(t, "align.go", contents, want)