Updated:

1 minute read

설명

  • https://github.com/swaggo/swag
  • Go 주석을 swagger 문서 2.0으로 변환
  • 명령어
    • swag 설치
      • go install github.com/swaggo/swag/cmd/swag@latest
    • init
      • 구문 분석 및 doc 생성
      • 의존성이 없는 경우
        • ~/go/bin/swag init
      • 의존성이 있는 경우
        • 다른 패키지의 구조체를 요청이나 응답으로 사용하는 경우 등
        • ~/go/bin/swag init --parseDependency
    • fmt
      • swag 주석에 swag 포맷 적용
      • ~/go/bin/swag init
  • Swagger UI
    • ip:port/swagger/index.html을 통해 접근 가능
    • api 확인 및 테스트 가능


예제

  • 코드
     package main
        
     import (
     	"context"
     	"net/http"
     	"os"
     	"os/signal"
     	"sync"
     	"syscall"
     	"time"
        
     	"test/docs"
        
     	"github.com/gorilla/mux"
     	httpSwagger "github.com/swaggo/http-swagger"
     )
        
     var server *http.Server
        
     type TestPostRequest struct {
     	Field1 string `json:"field_1",omitempty example:"value"`
     }
        
     type ResponseSuccess struct {
     	Field1 string `json:"field_1"`
     }
        
     type ResponseFailure struct {
     	Cause string `json:"cause"`
     }
        
     func loggingMiddleware(next http.Handler) http.Handler {
     	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
     		println(r.RequestURI, r.Method, "start")
     		defer println(r.RequestURI, r.Method, "end")
        
     		next.ServeHTTP(w, r)
     	})
     }
        
     // @Summary get test
     // @Description get test
     // @Accept json
     // @Produce json
     // @Param param_1 query string true "param_1 selection" Enums(1, 2, 3)
     // @Param param_2 query string true "param_2 selection" Enums(A, B, C, D) default(A)
     // @Param param_3 query string true "param_3" default(AAA)
     // @Param id path string true "id" default(id_1)
     // @Success 200 {object} ResponseSuccess
     // @Failure default {object} ResponseFailure
     // @Router /v1/test/{id} [get]
     // @tags test
     func testGet(w http.ResponseWriter, r *http.Request) {
     	w.WriteHeader(http.StatusOK)
     	w.Write([]byte(`{"field_1" : "get ok"}`))
     }
        
     // @Summary post test
     // @Description post test
     // @Accept json
     // @Produce json
     // @Param id path string true "id" default(aaa)
     // @Param request body TestPostRequest true "country selection"
     // @Success 200 {object} ResponseSuccess
     // @Failure default {object} ResponseFailure
     // @Router /v1/test [post]
     // @tags test
     func testPost(w http.ResponseWriter, r *http.Request) {
     	w.WriteHeader(http.StatusOK)
     	w.Write([]byte(`{"cause" : "post fail"}`))
     }
        
     func run(wg *sync.WaitGroup, done chan int) {
     	defer wg.Done()
        
     	go finalize(done)
        
     	docs.SwaggerInfo.Version = "1.0"
     	docs.SwaggerInfo.Host = "127.0.0.1:10000"
     	docs.SwaggerInfo.BasePath = ""
     	docs.SwaggerInfo.Title = "test"
     	docs.SwaggerInfo.Description = "test"
        
     	router := mux.NewRouter()
        
     	router.Use(loggingMiddleware)
        
     	router.PathPrefix("/swagger/").Handler(httpSwagger.WrapHandler)
     	router.HandleFunc("/v1/test/{id:[a-z,A-Z][a-z,A-Z,0-9,--,_,.]+}", testGet).Methods("GET")
     	router.HandleFunc("/v1/test", testPost).Methods("POST")
        
     	server = &http.Server{
     		Addr:    ":10000",
     		Handler: router}
        
     	server.ListenAndServe()
     }
        
     func finalize(done chan int) {
     	for len(done) == 1 {
     		time.Sleep(1 * time.Second)
     	}
        
     	if server != nil {
     		ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
     		cancel()
     		server.Shutdown(ctx)
     	}
     }
        
     func main() {
     	var wg sync.WaitGroup
        
     	done := make(chan int, 1)
     	done <- 1
        
     	signals := make(chan os.Signal, 1)
     	signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM)
        
     	wg.Add(1)
     	go run(&wg, done)
        
     	<-signals
        
     	<-done
        
     	wg.Wait()
     }
    
  • 실행 결과