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

// 如果 http method 映射成功,那么路由就是 names[1:]
// 如果沒(méi)有映射成功路由就是 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
}

最后我們?cè)谑褂?go template 生成最開(kāi)始方案中文件即可,代碼有點(diǎn)多了這里就不貼了,可以在 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 插件用來(lái)附加額外的 Struct tags,protoc-gen-go 目前暫時(shí)不支持添加 tag

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

 protoc -I ./example/api \
# 這個(gè)是用來(lái)生成 swagger json 文件的,我們很多系統(tǒng)支持導(dǎo)入 swagger 的定義,生成這個(gè)方便導(dǎo)入
--openapiv2_out ./example/api --openapiv2_opt logtostderr=true --openapiv2_opt json_names_for_fields=false \
# 生成對(duì)應(yīng)的 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

總結(jié)

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

參考文獻(xiàn)

  1. Go 進(jìn)階訓(xùn)練營(yíng)-極客時(shí)間
  2. Go 工程化(二) 項(xiàng)目目錄結(jié)構(gòu)
  3. https://github.com/go-kratos/kratos
  4. https://github.com/golang/protobuf/blob/master/protoc-gen-go/main.go

文章轉(zhuǎn)自微信公眾號(hào)@mohuishou

上一篇:

Go工程化(四) API 設(shè)計(jì)上: 項(xiàng)目結(jié)構(gòu) & 設(shè)計(jì)

下一篇:

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

我們有何不同?

API服務(wù)商零注冊(cè)

多API并行試用

數(shù)據(jù)驅(qū)動(dòng)選型,提升決策效率

查看全部API→
??

熱門(mén)場(chǎng)景實(shí)測(cè),選對(duì)API

#AI文本生成大模型API

對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力

25個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)

#AI深度推理大模型API

對(duì)比大模型API的邏輯推理準(zhǔn)確性、分析深度、可視化建議合理性

10個(gè)渠道
一鍵對(duì)比試用API 限時(shí)免費(fèi)