일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
- SWIFT
- insert
- mysql
- nmap
- Materials
- postgres
- ftp
- Jupyter
- GoCD
- STF_PortForwarding
- appium server
- nGrinder
- STF
- Jupyter Notebook
- PYTHON
- perfect
- openpyxl
- postgresql
- appium
- create table
- ssh
- kitura
- sshpass
- 28015
- centos
- rethinkdb
- port forwarding
- nohup
- 실행권한
- ubuntu
- Today
- Total
don't stop believing
[swag] Gin에서 Swagger 사용하기 본문
API 서버를 만드는데있어 문서화는 필수입니다.
Gin에서 Swagger를 사용하는 걸 확인해 보겠습니다.
https://github.com/swaggo/gin-swagger
먼저 Go에서 swag를 사용할 수 있게 source code를 다운로드 합니다.
$ go get -u github.com/swaggo/swag/cmd/swag
swag가 잘 다운로드 돼었는지 확인해 봅니다.
$ ll $GOPATH/src/github.com/swaggo total 0 drwxr-xr-x 3 tongchunkim staff 96B 3 4 17:58 . drwxr-xr-x 30 tongchunkim staff 960B 3 4 17:58 .. drwxr-xr-x 34 tongchunkim staff 1.1K 3 4 17:58 swag
이제 프로젝트 폴더를 하나 만들고 swag init을 해줍니다.
저는 testSwagger라고 폴더를 만들었습니다. 그리고 그 안에 swag init 을 했습니다.
$ mkdir testSwagger && cd testSwagger $ swag init 2019/03/04 18:10:47 Generate swagger docs.... 2019/03/04 18:10:47 Generate general API Info 2019/03/04 18:10:47 create docs.go at docs/docs.go
swag init을 하면 docs 폴더와 그 하외에 swagger 파일이 생성됩니다.
이제 main package를 만들어 봅니다.
저는 server.go로 만들고 이전에 사용했던 Parameters in path 예제를 그대로 가져다 사용해 만들었습니다. (조금 추가/수정했습니다.)
https://dejavuqa.tistory.com/320?category=320633
package main import ( "github.com/gin-gonic/gin" ) type welcomeModel struct { ID int `json:"id" example:"1" format:"int64"` Name string `json:"name" example:"account name"` } func setupRouter() *gin.Engine { r := gin.Default() r.GET("/welcome/:name", welcomePathParam) return r } func welcomePathParam(c *gin.Context) { name := c.Param("name") message := name + " is very handsome!" welcomeMessage := welcomeModel{1, message} c.JSON(200, gin.H{"message": welcomeMessage}) } func main() { r := setupRouter() r.Run() // Listen and Server in 0.0.0.0:8080 }
이제 swagger 연동을 시작하겠습니다.
gin-swagger를 다운로드 합니다.
$ go get -u github.com/swaggo/gin-swagger $ go get -u github.com/swaggo/gin-swagger/swaggerFiles
다운로드한 package를 server.go의 import에 추가합니다.
그리고 swag init으로 생성된 docs package도 추가해 줍니다. docs package를 추가하려면 GOPATH의 src 하위 경로로 잡아주면 됩니다.
import (
"github.com/gin-gonic/gin"
ginSwagger "github.com/swaggo/gin-swagger"
swaggerFiles "github.com/swaggo/gin-swagger/swaggerFiles"
"github.com/dejavuwing/testSwagger/docs")
그리고 setupRouter() 함수에 swagger route를 추가해 줍니다.
r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler))
이제 welcomePathParma() 함수 위에 annotation을 아래와 같이 추가합니다.
// Welcome godoc
// @Summary Summary를 적어 줍니다.
// @Description 자세한 설명은 이곳에 적습니다.
// @name get-string-by-int
// @Accept json
// @Produce json
// @Param name path string true "User name"
// @Router /welcome/{name} [get]
// @Success 200 {object} welcomeModel
위에서 설명한 코드를 추가한 전체 코드는 아래와 같습니다.
package main import ( "github.com/gin-gonic/gin" "github.com/dejavuwing/testSwagger/docs" ginSwagger "github.com/swaggo/gin-swagger" swaggerFiles "github.com/swaggo/gin-swagger/swaggerFiles" ) type welcomeModel struct { ID int `json:"id" example:"1" format:"int64"` Name string `json:"name" example:"account name"` } func setupRouter() *gin.Engine { r := gin.Default() r.GET("/welcome/:name", welcomePathParam) r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) return r } // Welcome godoc // @Summary Summary를 적어 줍니다. // @Description 자세한 설명은 이곳에 적습니다. // @name get-string-by-int // @Accept json // @Produce json // @Param name path string true "User name" // @Router /welcome/{name} [get] // @Success 200 {object} welcomeModel func welcomePathParam(c *gin.Context) { name := c.Param("name") message := name + " is very handsome!" welcomeMessage := welcomeModel{1, message} // welcomeMessage := model.User{ID: 1, Name: name} c.JSON(200, gin.H{"message": welcomeMessage}) } func main() { // programatically set swagger info docs.SwaggerInfo.Title = "Swagger Example API" docs.SwaggerInfo.Description = "This is a sample server for Swagger." docs.SwaggerInfo.Version = "1.0" docs.SwaggerInfo.Host = "petstore.swagger.io" docs.SwaggerInfo.BasePath = "/v2" r := setupRouter() r.Run() // Listen and Server in 0.0.0.0:8080 }
swagger로 변환하기 위해 swag init을 한번 더 해줍니다.
annotation으로된 swagger 문서가 변경되거나 할 경우 swag init을 다시 해줘야 합니다.
$ swag init 2019/03/05 17:52:14 Generate swagger docs.... 2019/03/05 17:52:14 Generate general API Info 2019/03/05 17:52:14 create docs.go at docs/docs.go
이제 server.go를 실행해 봅니다.
$ go run server.go [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /welcome/:name --> main.welcomePathParam (3 handlers) [GIN-debug] GET /swagger/*any --> github.com/swaggo/gin-swagger.WrapHandler.func1 (3 handlers) [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080
만약 server.go를 실행했을때 아래와 같은 메시지가 나온다면 github.com/alecthomas/template package를 다운받아야 합니다.
$ go run server.go docs/docs.go:10:2: cannot find package "github.com/alecthomas/template" in any of: /usr/local/opt/go/libexec/src/github.com/alecthomas/template (from $GOROOT) /Users/tongchunkim/go/src/github.com/alecthomas/template (from $GOPATH)
swag init으로 생성된 docs에서 github.com/alecthomas/template를 사용하고 있습니다.
$ go get -u github.com/alecthomas/template
정상적으로 server.go가 실행되었다면 아래 경로로 swagger를 호출해 봅니다.
http://localhost:8080/swagger/index.html
그런데 Errors 메시지가 나오네요.
우선 GET /welcome/{name}을 클릭해 봅니다.
annotation으로 작성한 문서가 잘 보이네요.
Errors 메세지를 확인해 보겠습니다.
struct로 작성된 welcomeModel이 문제인것 같습니다.
이걸 해결하기 위해 Web Server (server.go)의 구조를 변경하겠습니다. Model을 별도의 package로 만들어 주겠습니다.
testSwagger폴더 아래 model 이란 폴더를 만들어 주고 그 안에 user.go를 만들어 줍니다.
tree 명령으로 확인하면 아래와 같습니다.
$ tree . ├── docs │ ├── docs.go │ └── swagger │ ├── swagger.json │ └── swagger.yaml ├── model │ └── user.go └── server.go 3 directories, 5 files
user.go 파일안에 user 데이터를 담을 수 있는 struct를 만들어 줍니다.
package 명은 model로 해줍니다.
package model type User struct { ID int `json:"id" example:"1"` Name string `json:"name" example:"user name"` }
이제 server.go에서 model package를 import하고 model.User에 데이터를 담아 json 형태로 response 해 줍니다.
그리고 swagger annotation 중 @Success 부분을 아래와 같이 변경합니다.
// @Success 200 {object} model.User
수정한 server.go 코드는 아래와 같습니다.
package main import ( "github.com/gin-gonic/gin" "github.com/dejavuwing/testSwagger/docs" "github.com/dejavuwing/testSwagger/model" ginSwagger "github.com/swaggo/gin-swagger" swaggerFiles "github.com/swaggo/gin-swagger/swaggerFiles" ) func setupRouter() *gin.Engine { r := gin.Default() r.GET("/welcome/:name", welcomePathParam) r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler)) return r } // Welcome godoc // @Summary Summary를 적어 줍니다. // @Description 자세한 설명은 이곳에 적습니다. // @name get-string-by-int // @Accept json // @Produce json // @Param name path string true "User name" // @Router /welcome/{name} [get] // @Success 200 {object} model.User func welcomePathParam(c *gin.Context) { name := c.Param("name") welcomeMessage := model.User{ID: 1, Name: name} c.JSON(200, gin.H{"message": welcomeMessage}) } func main() { // programatically set swagger info docs.SwaggerInfo.Title = "Swagger Example API" docs.SwaggerInfo.Description = "This is a sample server for Swagger." docs.SwaggerInfo.Version = "1.0" docs.SwaggerInfo.Host = "petstore.swagger.io" docs.SwaggerInfo.BasePath = "/v2" r := setupRouter() r.Run() // Listen and Server in 0.0.0.0:8080 }
코드에 수정이 있으니 다시 swag init을 해줍니다.
$ swag init 2019/03/05 18:23:27 Generate swagger docs.... 2019/03/05 18:23:27 Generate general API Info 2019/03/05 18:23:27 Generating model.User 2019/03/05 18:23:27 create docs.go at docs/docs.go
이전에는 없었던 model.User도 Generating되는게 보입니다.
server.go를 실행해 줍니다.
$ go run server.go [GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached. [GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production. - using env: export GIN_MODE=release - using code: gin.SetMode(gin.ReleaseMode) [GIN-debug] GET /welcome/:name --> main.welcomePathParam (3 handlers) [GIN-debug] GET /swagger/*any --> github.com/swaggo/gin-swagger.WrapHandler.func1 (3 handlers) [GIN-debug] Environment variable PORT is undefined. Using port :8080 by default [GIN-debug] Listening and serving HTTP on :8080
swagger를 다시 실행해 보겠습니다.
Errors 메시지가 없어지고 Models package의 model.User struct가 새로 보입니다.
여기까지가 golang (gin)에서 swagger를 사용하는 방법이었습니다.
세부적인 annotation은 아래 설명 페이지나 example 에서 확인할 수 있습니다.
https://github.com/swaggo/swag#api-operation
https://github.com/swaggo/swag/tree/master/example
'Golang > Gin' 카테고리의 다른 글
Model binding and validation (0) | 2019.03.06 |
---|---|
mysql curd (with Gin) (0) | 2019.03.06 |
Grouping routes (0) | 2019.03.04 |
Upload files (0) | 2019.02.27 |
Map as querystring or postform parameters (0) | 2019.02.27 |