Kitex 代碼生成工具

2022-04-27 10:13 更新

代碼生成工具

kitex 是 Kitex 框架提供的用于生成代碼的一個命令行工具。目前,kitex 支持 thrift 和 protobuf 的 IDL,并支持生成一個服務端項目的骨架。

安裝

go install github.com/cloudwego/kitex/tool/cmd/kitex

用 go 命令來安裝是最簡單的,你也可以選擇自己從源碼構建和安裝。要查看 kitex 的安裝位置,可以用:

go list -f {{.Target}} github.com/cloudwego/kitex/tool/cmd/kitex

注意,由于 kitex 會為自身的二進制文件創(chuàng)建軟鏈接,因此請確保 kitex 的安裝路徑具有可寫權限。

依賴與運行模式

底層編譯器

要使用 thrift 或 protobuf 的 IDL 生成代碼,需要安裝相應的編譯器:thriftgo 或 protoc。

kitex 生成的代碼里,一部分是底層的編譯器生成的(通常是關于 IDL 里定義的結構體的編解碼邏輯),另一部分是用于連接 Kitex 框架與生成代碼并提供給終端用戶良好界面的膠水代碼。

從執(zhí)行流上來說,當 kitex 被要求來給一個 thrift IDL 生成代碼時,kitex 會調用 thriftgo 來生成結構體編解碼代碼,并將自身作為 thriftgo 的一個插件(名為 thrift-gen-kitex)來執(zhí)行來生成膠水代碼。當用于 protobuf IDL 時亦是如此。

而以哪個名字運行,決定了 kitex 的執(zhí)行模式是命令行入口還是一個插件(thriftgo 的或 protoc 的),所以 kitex 的安裝目錄需要具備可寫權限,用于 kitex 建立必要的軟鏈接以區(qū)分不同的執(zhí)行模式。

{#content}gt; kitex IDL
    |
    | thrift-IDL
    |---------> thriftgo --gen go:... -plugin=... -out ... IDL
    |        |
    |        -----> thrift-gen-kitex (symbol link to kitex)
    |
    | protobuf-IDL
    ----------> protoc --kitex_out=... --kitex_opt=... IDL
             |
             -----> protoc-gen-kitex (symbol link to kitex)

庫依賴

kitex 生成的代碼會依賴相應的 Go 語言代碼庫:

  • 對于 thrift IDL,是 ?github.com/apache/thrift v0.13.0 ?
  • 對于 protobuf IDL,是 ?google.golang.org/protobuf v1.26.0?

要注意的一個地方是,?github.com/apache/thrift/lib/go/thrift? 的 ?v0.14.0? 版本開始提供的 API 和之前的版本是不兼容的,如果在更新依賴的時候給 ?go get? 命令增加了 ?-u? 選項,會導致該庫更新到不兼容的版本造成編譯失敗。你可以通過額外執(zhí)行一個命令來指定正確的版本:

go get github.com/apache/thrift@v0.13.0
    

或用 ?replace ?指令強制固定該版本:

go mod edit -replace github.com/apache/thrift=github.com/apache/thrift@v0.13.0

使用 protobuf IDL 的注意事項

kitex 僅支持 protocol buffers 的 proto3 版本的語法。

IDL 里的 ?go_package? 是必需的,其值可以是一個用點(?.?)或斜線(?/?)分隔的包名序列,決定了生成的 import path 的后綴。例如

option go_package = "hello.world"; // or hello/world

生成的 import path 會是 ?${當前目錄的 import path}/kitex_gen/hello/world?。

使用

基礎使用 

語法:?kitex [options] IDL?

生成客戶端代碼

kitex path_to_your_idl.thrift

執(zhí)行后在當前目錄下會生成一個名為 kitex_gen 目錄,其中包含了 IDL 定義的數(shù)據結構,以及與 IDL 里定義的 service 相對應的 ?*service? 包,提供了創(chuàng)建這些 service 的 client API。

生成服務端代碼

kitex -service service_name path_to_your_idl.thrift

執(zhí)行后在當前目錄下會生成一個名為 kitex_gen 目錄,同時包含一些用于創(chuàng)建和運行一個服務的腳手架代碼。

生成代碼的結構

假設我們有兩個 thrift IDL 文件,demo.thrift 和 base.thrift,其中 demo.thrift 依賴了 base.thrift,并且 demo.thrift 里定義了一個名為 ?demo ?的 service 而 base 里沒有 service 定義。

那么在一個空目錄下,?kitex -service demo demo.thrift? 生成的結果如下:

.
├── build.sh                     // 服務的構建腳本,會創(chuàng)建一個名為 output 的目錄并生成啟動服務所需的文件到里面
├── handler.go                   // 用戶在該文件里實現(xiàn) IDL service 定義的方法
├── kitex_gen                    // IDL 內容相關的生成代碼
│   ├── base                     // base.thrift 的生成代碼
│   │   ├── base.go              // thriftgo 的產物,包含 base.thrift 定義的內容的 go 代碼
│   │   └── k-base.go            // kitex 在 thriftgo 的產物之外生成的代碼
│   └── demo                     // demo.thrift 的生成代碼
│       ├── demo.go              // thriftgo 的產物,包含 demo.thrift 定義的內容的 go 代碼
│       ├── k-demo.go            // kitex 在 thriftgo 的產物之外生成的代碼
│       └── demoservice          // kitex 為 demo.thrift 里定義的 demo service 生成的代碼
│           ├── demoservice.go   // 提供了 client.go 和 server.go 共用的一些定義
│           ├── client.go        // 提供了 NewClient API
│           └── server.go        // 提供了 NewServer API
├── main.go                      // 程序入口
└── script                       // 構建腳本
    └── bootstrap.sh             // 服務的啟動腳本,會被 build.sh 拷貝至 output 下

如果不指定 ?-service? 參數(shù),那么生成的只有 kitex_gen 目錄。

選項 

本文描述的選項可能會過時,可以用 ?kitex -h? 或 ?kitex --help? 來查看 kitex 的所有可用的選項。

-service service_name

使用該選項時,kitex 會生成構建一個服務的腳手架代碼,參數(shù) ?service_name ?給出啟動時服務自身的名字,通常其值取決于使用 Kitex 框架時搭配的服務注冊和服務發(fā)現(xiàn)功能。

-module module_name

該參數(shù)用于指定生成代碼所屬的 Go 模塊,會影響生成代碼里的 import path。

  1. 如果當前目錄是在 ?$GOPATH/src? 下的一個目錄,那么可以不指定該參數(shù);kitex 會使用 ?$GOPATH/src? 開始的相對路徑作為 import path 前綴。例如,在 ?$GOPATH/src/example.com/hello/world? 下執(zhí)行 kitex,那么 ?kitex_gen/example_package/example_package.go? 在其他代碼代碼里的 import path 會是 ?example.com/hello/world/kitex_gen/example_package?。
  2. 如果當前目錄不在 ?$GOPATH/src? 下,那么必須指定該參數(shù)。
  3. 如果指定了 ?-module? 參數(shù),那么 kitex 會從當前目錄開始往上層搜索 go.mod 文件
    • 如果不存在 go.mod 文件,那么 kitex 會調用 ?go mod init? 生成 go.mod;
    • 如果存在 go.mod 文件,那么 kitex 會檢查 ?-module? 的參數(shù)和 go.mod 里的模塊名字是否一致,如果不一致則會報錯退出;
    • 最后,go.mod 的位置及其模塊名字會決定生成代碼里的 import path。

-I path

添加一個 IDL 的搜索路徑。

-type type

指明當前使用的 IDL 類型,當前可選的值有 thrift(默認)和 protobuf。

-v 或 -verbose

輸出更多日志。

高級選項

-use path

在生成服務端代碼(使用了 ?-service?)時,可以用 ?-use? 選項來讓 kitex 不生成 kitex_gen 目錄,而使用該選項給出的 import path。

-combine-service 

對于 thrift IDL,kitex 在生成服務端代碼腳手架時,只會針對最后一個 service 生成相關的定義。如果你的 IDL 里定義了多個 service 定義并且希望在一個服務里同時提供這些 service 定義的能力時,可以使用 ?-combine-service? 選項。

該選項會生成一個合并了目標 IDL 文件中所有 service 方法的 ?CombineService?,并將其用作 main 包里使用的 service 定義。注意這個模式下,被合并的 service 之間不能有沖突的方法名。

-protobuf value

傳遞給 protoc 的參數(shù)。會拼接在 ?-go_out? 的參數(shù)后面??捎玫闹祬⒖?nbsp;?protoc ?的幫助文檔。

-thrift value

傳遞給 thriftgo 的參數(shù)。會拼接在 ?-g go:? 的參數(shù)后面??捎玫闹祬⒖?nbsp;?thriftgo ?的幫助文檔。kitex 默認傳遞了 ?naming_style=golint,ignore_initialisms,gen_setter,gen_deep_equal?,可以被覆蓋。


以上內容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號