// 分割方法名
names := strings.Split(toSnakeCase(m.GoName), "_")
// ...

// 如果 http method 映射成功,那么路由就是 names[1:]
// 如果沒有映射成功路由就是 names
switch strings.ToUpper(names[0]) {
case http.MethodGet, "FIND", "QUERY", "LIST", "SEARCH":
httpMethod = http.MethodGet
// ... 其他方法映射
default:
httpMethod = "POST"
paths = names
}

// ...

md := buildMethodDesc(m, httpMethod, path)
return md
}

最后我們在使用 go template 生成最開始方案中文件即可,代碼有點多了這里就不貼了,可以在 https://github.com/mohuishou/protoc-gen-go-gin 中找到

使用案例

案例完整源代碼可以在 https://github.com/mohuishou/protoc-gen-go-gin 中找到

syntax = "proto3";
?
option go_package = "github.com/mohuishou/protoc-gen-go-gin/example/api/product/app/v1";
?
package product.app.v1;
?
import "google/api/annotations.proto";
?
// blog service is a blog demo
service BlogService {
rpc GetArticles(GetArticlesReq) returns (GetArticlesResp) {
option (google.api.http) = {
get: "/v1/articles"
additional_bindings {
get: "/v1/author/{author_id}/articles"
}
};
}
?
rpc CreateArticle(Article) returns (Article) {
option (google.api.http) = {
post: "/v1/author/{author_id}/articles"
};
}
}
?
message GetArticlesReq {
// @inject_tag: form:"title"
string title = 1;
?
// @inject_tag: form:"page"
int32 page = 2;
?
// @inject_tag: form:"page_size"
int32 page_size = 3;
?
// @inject_tag: form:"author_id" uri:"author_id"
int32 author_id = 4;
}
?
message GetArticlesResp {
int64 total = 1;
repeated Article articles = 2;
}
?
message Article {
string title = 1;
string content = 2;
// @inject_tag: form:"author_id" uri:"author_id"
int32 author_id = 3;
}

注意 @inject_tag: 的注釋是使用了 protoc-go-inject-tag 插件用來附加額外的 Struct tags,protoc-gen-go 目前暫時不支持添加 tag

定義好 proto 文件之后我們只需要執行命令

 protoc -I ./example/api \
# 這個是用來生成 swagger json 文件的,我們很多系統支持導入 swagger 的定義,生成這個方便導入
--openapiv2_out ./example/api --openapiv2_opt logtostderr=true --openapiv2_opt json_names_for_fields=false \
# 生成對應的 go 文件
--go_out ./example/api --go_opt=paths=source_relative \
# 生成本文插件中的 gin 文件
--go-gin_out ./example/api --go-gin_opt=paths=source_relative \
example/api/product/app/v1/v1.proto
protoc-go-inject-tag -input=./example/api/product/app/v1/v1.pb.go

總結

api 設計這部分就先到這里了,下一篇文章我們一起看看配置管理

參考文獻

  1. Go 進階訓練營-極客時間
  2. Go 工程化(二) 項目目錄結構
  3. https://github.com/go-kratos/kratos
  4. https://github.com/golang/protobuf/blob/master/protoc-gen-go/main.go

文章轉自微信公眾號@mohuishou

上一篇:

Go工程化(四) API 設計上: 項目結構 & 設計

下一篇:

從gin框架看如何構建自己的http服務框架
#你可能也喜歡這些API文章!

我們有何不同?

API服務商零注冊

多API并行試用

數據驅動選型,提升決策效率

查看全部API→
??

熱門場景實測,選對API

#AI文本生成大模型API

對比大模型API的內容創意新穎性、情感共鳴力、商業轉化潛力

25個渠道
一鍵對比試用API 限時免費

#AI深度推理大模型API

對比大模型API的邏輯推理準確性、分析深度、可視化建議合理性

10個渠道
一鍵對比試用API 限時免費