golang+swagger+mux配置

1. install and import swagger

参考https://www.soberkoder.com/swagger-go-api-swaggo/

step 1:

install swagger related tool:

go get -u github.com/swaggo/swag/cmd/swag
go get -u github.com/swaggo/http-swagger
go get -u github.com/alecthomas/template

 

step 2:

in main.go, import related package:

_ "xxx/docs" // this xxx name your real golang project package name, from "go mod init xxx" command  
httpSwagger "github.com/swaggo/http-swagger"
"github.com/gorilla/mux" 
"bytes"
"net/url"
"github.com/tidwall/gjson"
"encoding/base64"
"fmt"
"encoding/json"

 

2. golang code and swagger annotation

step 1, add following annotation before main() function or your related function. if before your non-main function, you need to add security related configuration in your doc.json file after "swag init" command

const (
	TokenURL = "https://xxxxx.com/v1/user/token"
)

// @title appstatusviewer
// @version 1.0
// @description appstatusviewer swagger
// @termsOfService http://swagger.io/terms/
// @contact.name API Support
// @contact.email [email protected]
// @license.name Apache 2.0
// @license.url http://www.apache.org/licenses/LICENSE-2.0.html
// @host localhost
// @BasePath /
// @securityDefinitions.basic BasicAuth
func (a *App) router() http.Handler {
    r := mux.NewRouter()
    r.Use(a.cors)
    r.Path("/swagger/testapi").HandlerFunc(a.getBranches)
    r.Path("/swagger/test/{app}").HandlerFunc(basicAuth(a.getApp)) //for api need username, password and generate token for authorization

    r.PathPrefix("/swagger").Handler(httpSwagger.WrapHandler)
    return r

}

func basicAuth(f func(http.ResponseWriter, *http.Request)) func(http.ResponseWriter, *http.Request) {
    return func(w http.ResponseWriter, r *http.Request) {
        reqToken := r.Header.Get("authorization")
        splitToken := strings.Split(reqToken, "Basic")

        if len(splitToken) != 2 {
            w.Write([]byte("Basic token not in proper format"))
            w.WriteHeader(http.StatusBadRequest)
            return
        }
        reqToken = strings.TrimSpace(splitToken[1])
        decoded, err := base64.StdEncoding.DecodeString(reqToken)

        if err != nil {
            w.Write([]byte("decode error"))
            w.WriteHeader(http.StatusBadRequest)
            return
        }
        result := strings.Split((string)(decoded), ":")
        if len(result) != 2 {
            w.Write([]byte("Basic token not in proper format"))
            w.WriteHeader(http.StatusBadRequest)
            return
        }

        data := url.Values{}
        data.Set("username", result[0])
        data.Add("password", result[1])
        req, err := http.NewRequest("POST", TokenURL, bytes.NewBufferString(data.Encode()))

        req.Header.Set("Content-Type", "application/x-www-form-urlencoded")

        if err != nil {
            fmt.Printf("Create get token http request error %v", err)
            w.Write([]byte("Create get token http request error"))
            w.WriteHeader(http.StatusInternalServerError)
            return
        }

        client := &http.Client{}
        resp, err := client.Do(req)

        if err != nil {
            fmt.Printf("Get jwt token error %v", err)
            w.Write([]byte("Get jwt token error"))
            w.WriteHeader(http.StatusInternalServerError)
            return
        }

        defer resp.Body.Close()
        body, err := ioutil.ReadAll(resp.Body)

        if err != nil {
            fmt.Printf("Read response body error %v", err)
            w.Write([]byte("Read response body error"))
            w.WriteHeader(http.StatusInternalServerError)
            return
        }

        accessToken := gjson.GetBytes(body, "data.access_token").String()
        if len(accessToken) == 0 {
            w.Write([]byte("No data.access_token"))
            w.WriteHeader(http.StatusInternalServerError)
            return
        }
        r.Header.Set("authorization", fmt.Sprintf("Bearer %s", accessToken))
        f(w, r)
    }

}


func (a *App) cors(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        o := r.Header.Get("Origin")
        if o == "" {
            o = "*"
        }

        h := w.Header()
        h.Set("Access-Control-Allow-Origin", o)
        h.Set("Access-Control-Allow-Methods", "*")
        h.Set("Access-Control-Allow-Headers", "*")

        if r.Method == "OPTIONS" {
            w.Write([]byte("OK"))
            return
        }
        next.ServeHTTP(w, r)
    })
}

// GetApp godoc
// @Summary Get app
// @Description Get app
// @Tags getApp
// @Accept  json
// @Produce  json
// @Param app path string true " "
// @Success 200
// @SecuritySchemes BasicAuth
// @SecuritySchemes OAuth2Application[write, admin]]
// @Router /swagger/test/{app} [get]
func (a *App) getApp(w http.ResponseWriter, r *http.Request) {
	vars := mux.Vars(r)
	app := vars["app"]

	if application == "forbidden" {
		http.Error(w, "The request is forbidden", http.StatusForbidden)
		return
	} else if application == "gateway" {
		http.Error(w, "The request is forbidden", http.StatusGatewayTimeout)
		return
	}


	data := make(map[string]interface{})
	data["app"] = app
	data["timestamp"] = "2020-06-18T07:02:33+00:00"

	b, err := json.Marshal(data)
	if err != nil {
		http.Error(w, "Failed to marshal", http.StatusInternalServerError)
		return
	}

	w.Header().Set("Content-Type", "application/json")
	w.Write([]byte(b))
}

step 2:

(1) execute command: swag init

(2) then: go run main.go  or package it by command:

go build -mod vendor -ldflags "-s -w -X main.build=177 -X main.branch=dev -X main.z=$(date +'%s')" -o pipeline/files/xxx

 

step 3:

other related golang command:

go mod init xxx(this name you can give any name, up to you)------ generate go.mod automatically

go build main.go (update go.mod file and create go.sum file automatically)

go mod vendor (When you import a new package, you need to use this command to download)

 

你可能感兴趣的:(golang)