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)