介面引數繫結, 公共處理程式碼生成工具

dengzi發表於2022-05-13

很久之前寫過一個自動建立, 校驗請求引數的文章: gin 自動對映引數及自動校驗, 文章介紹了一種透過反射建立請求引數, 繫結請求引數到例項, 校驗處理, 並呼叫 HandlerFunc 的手段. 最近我想到用程式碼生成來做這個功能, 這樣就沒有反射帶來的效能問題, 順便玩一下 go 語言超程式設計.

使用該工具後, 介面處理函式將變成下面這樣:

func TestHandler(ctx *gin.Context, request *param.Request) (*param.Response, error) 

這個工具可以生成一個包裝函式, 幫你做那些無聊的操作, 比如建立請求引數結構體, 繫結請求引數, 繫結響應, 校驗引數等等之類的, 生成的包裝函式再呼叫這個函式處理真正的業務, 設定路由的時候改成生成的包裝函式即可.

安裝

這個是一個工具, 不會依賴到專案, 如果出現找不到命令, 記得新增 gopath/bin 目錄到環境變數.

go install github.com/dengzii/genx

效果

使用 genx 後, 我們的 API 處理函式就變成下面這樣子了, 函式第二個引數就是請求繫結的結構體, 返回的分別是響應體和錯誤, 所有引數都是可選的, 但是順序不可變, 可選指標, 例如沒有請求引數則去除第二個引數即可.

//go:generate genx handler
func TestHandler(ctx *gin.Context, request *param.TestRequest) (*param.TestResponse, error) {
// ...
return &param.LoginResponse{Token: "token"}, nil
}

只需要給函式新增一行註釋, 註釋沒有要求必須是函式註釋第幾行, 注意 // 後面沒有空格, goland 左側就會出現一個執行按鈕, 也可以在包目錄下執行 go generate 命令或者 genx, 工具會掃描當前包下所有帶有該註釋的函式, 並且以檔案做劃分生成對應的繫結引數程式碼.

//go:generate genx handler

生成後的程式碼大概如下

func GenxTestHandler(ctx *gin.Context) {
   req := &param.LoginRequest{}
   _ = ctx.BindJSON(req)
   resp, err := TestHandler(ctx, req)
   if err != nil {
      ctx.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
      return
   }
   ctx.JSON(http.StatusOK, resp)
}

之後我們繫結路由的時候就在原函式前加一個 Genx 字首即可

計劃

目前只支援最基礎的功能: 繫結引數, 校驗什麼的都還沒有, 暫時只支援 gin, 不知道大家對這個小工具的看法如何, 歡迎在評論區發表你的看法.

  • 生成 api handler func 繫結函式
  • 生成繫結 json 請求引數到結構體
  • 生成繫結 json 響應
  • 支援定多種引數型別(Query, Form 等)
  • 支援 gin 外的 web framework
  • 自定義校驗器支援
  • 生成公共響應包裝
  • 引數校驗
  • 錯誤處理及自定義處理過程

github: github.com/dengzii/genx

覺得不錯的話 star 一下吧, 任何想法都可以在 issue 中提交.

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章