IT/Go

[Go/Golang] Echo 프레임워크에서 Swagger 사용하기

wookiist 2021. 3. 9. 10:51

Echo 프레임워크에서 Swagger 사용하기

Echo

Echo 프레임워크는 Golang 웹 프레임워크 프로젝트 중 하나입니다. Gin이라는 유명한 프레임워크도 있지만, 저는 Echo를 처음으로 접해서 지금까지 Echo로 사용해오고 있습니다. 아직 Gin을 이용해보진 못해서 둘을 자세히 비교할 수는 없겠지만, 표면적으로는 최근 들어, Echo가 Gin에 비해 더 많이 검색되고 있고, Gin 보다 짧은 Release Cycle을 가져가고 있다는 점이 눈에 띕니다. 참고

Swaggo

한편, Swagger는 API의 문서화를 자동으로 처리해주는 프로젝트입니다. 기존의 docs 등을 이용한 API 문서 관리 기술은 API가 변하게 되면 변한 API에 맞춰 문서화를 다시 진행해야 하는 번거로움이 있었다면, 이런 번거로움을 해소시켜주는 고마운 녀석입니다.

Swaggo는 이런 Swagger를 Golang에서 잘 활용할 수 있도록 도와주는 도구 프로젝트입니다. 본 포스트에서는 Swagger 2.0의 RESTful API 문서를 자동으로 생성해주는 swaggo/swag와 Echo 프레임워크의 Middleware로 동작하여 Swagger를 사용할 수 있도록 도와주는 swaggo/echo-swagger를 활용할 것입니다.

튜토리얼

필요 패키지 설치

본 튜토리얼을 따라오는 데 필요한 패키지를 다운로드하여 설치해보겠습니다. 다음의 패키지가 필요합니다.

  • "github.com/swaggo/swag/cmd/swag"
  • "github.com/swaggo/echo-swagger"
$ go get github.com/swaggo/swag/cmd/swag
$ go get github.com/swaggo/echo-swagger

go module 업데이트

필요한 패키지가 다운로드 및 설치되었다면 다음의 명령어로 gomodule에 필요한 패키지들을 업데이트 합니다.

$ go mod tidy

(주의) go mod tidy 이후에도 사용하고 있는 IDE에 따라 정상 동작하고 있지 않을 수 있습니다. 해당 부분은 개별적으로 해결하신 후 아래를 따라와 주시기 바랍니다.

Declarative Comments

이제 API 소스 코드에 Declarative Comments를 작성합니다. Declarative Comments 형식은 다음을 참조합니다.

Parameter

Declarative Comments로 Parameter를 명시하는 방법은 아래와 같습니다.

// @Param {Param Name} {Param Type} {Data Type} {isMandatory} {Description} 

Declarative Comments에서 지원하는 Parameter Type은 다음과 같습니다.

  • query
  • path
  • header
  • body
  • formData

또한 다음의 Data Type을 지원하고 있습니다.

  • string (string)
  • integer (int, uint, uint32, uint64)
  • number (float32)
  • boolean (bool)
  • user defined struct

만약 반드시 입력받아야 하는 String 타입의 query parameter 데이터라면, 주석에 다음처럼 넣어주시면 됩니다.

// @Param example query string true "Example param"

더욱 자세한 내용은 다음을 참조해주세요.

본 포스트에서는 편의상 모든 핸들러 함수가 main.go에 작성되어 있다고 가정하겠습니다.

다음의 코드에 작성된 주석에 주목해주세요.

package main

import (
    "net/http"
    _ "{package_name}/docs"
    echoSwagger "github.com/swaggo/echo-swagger"
    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
)

// User struct
type User struct {
    name string `json:"name"`
    age int `json:"age"`
}

// @title Wookiist Sample Swagger API
// @version 1.0
// @host localhost:30000
// @BasePath /api/v1
func main() {
    e := echo.New()
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())

    e.GET("/api/v1/user/:name", getUser)
    e.POST("/api/v1/user", createUser)

    e.GET("/swagger/*", echoSwagger.WrapHandler)

    e.Logger.Fatal(e.Start(":30000"))
}

// @Summary Get user
// @Description Get user's info
// @Accept json
// @Produce json
// @Param name path string true "name of the user"
// @Success 200 {object} User
// @Router /user/{name} [get]
func getUser(c echo.Context) error {
    user := mockUser
    // 중략
    return c.JSONPretty(http.StatusOK, *user, "  ")
}

// @Summary Create user
// @Description Create new user
// @Accept json
// @Produce json
// @Param userBody body User true "User Info Body"
// @Success 200 {object} User
// @Router /user [post]
func createUser(c echo.Context) error {
    user := new(User)
    // 중략
    return c.JSONPretty(http.StatusOK, *user, "  ")
}

이렇게 main과 각 handler 함수에 Declarative Comments를 달아주면 Swagger 문서로 변환하기 직전까지의 작업이 완료된 것입니다.

만약 main이 아닌 다른 파일에서 handler를 작성하였다면, 해당 파일 내의 handler 함수에 주석을 달아주시면 되겠습니다.

만약 바로 실행되는 예제가 필요하시다면 swaggo의 예제를 일부 변형한 다음의 코드를 참조하여 주세요. 그리고 해당 코드가 도움이 되셨다면 ⭐STAR 한 번씩만 부탁드립니다 😉

전체 코드 : https://github.com/wookiist/wookiist-tistory-code/blob/master/code210309-1/main.go

swag 실행

이제 이전 단계에서 작성한 주석을 Swagger 문서로 변환할 차례입니다. 아래 명령어를 실행해주세요. 만약 main.go가 아닌 별도의 파일에 작성하셨다면 -g 옵션 이후에 main.go가 아닌 해당 파일의 경로를 입력해주시면 됩니다.

$ swag init
# 또는 $ swag init -g something.go

해당 명령을 실행하면, 아래처럼 프로젝트의 루트 디렉터리에 /docs 디렉터리가 생성되었을 것입니다.

docs
├── docs.go
├── swagger.json
└── swagger.yaml

0 directories, 3 files

swag를 실행하면 위처럼 docs.go, swagger.json, swagger.yaml 파일 3개를 만들어 줍니다. 이 파일들은 이전에 Declarative Comments로 작성해둔 내용을 swag가 파싱 하여 제작한 파일들로, 이제 이 패키지를 import 하여 Swagger를 실행하면 됩니다.

import docs

위에서 생성한 docs 패키지를 import 합니다. 많은 튜토리얼에서 이 부분을 생략하거나, example docs를 import 하는 쪽으로 대체하고 있는데요, 이 경우 작성한 Swagger가 전혀 보이지 않거나, example docs에 포함된 내용이 보이게 됩니다. 꼭! 본인이 작성하신 docs 패키지를 import 해주세요. 대부분의 경우 다음처럼 따라 하시면 됩니다.

// main.go에서 작성
import (
    // ... 중략
    _ "{package_name}/docs"
)

Run

이제 go run main.goF5 든 활용 해서 프로그램을 실행시켜 봅시다. 그리고, 우리가 작성한 Swagger 페이지에 접속해봅니다. 만약 이 튜토리얼대로 따라오셨다면 다음의 URL로 접속하시면 됩니다.

http://localhost:30000/swagger/index.html

swagger_img

만약 API에 변화가 있거나 Declarative Comment를 변경한 경우, swag init 을 다시 수행해주셔야 함을 잊지 마세요.

마무리

여기까지 따라오시느라 고생이 많으셨습니다. 만약 이 튜토리얼이 도움이 되셨다면 글 좌측 하단의 하트❤를 눌러주시면 감사하겠습니다.

혹시라도 튜토리얼에 이상이 있거나, 이해가 가지 않으시는 부분, 또는 추가적으로 궁금하신 내용이 있다면 주저 마시고 댓글💬을 남겨주세요! 빠른 시간 안에 답변을 드리겠습니다 😊

참고

반응형