
2024年在線市場(chǎng)平臺(tái)的11大最佳支付解決方案
如上圖所示于此同時(shí)我們還可以利用 protobuf 文件生成對(duì)應(yīng)語(yǔ)言的客戶端代碼,就不用每個(gè)項(xiàng)目都去維護(hù)一套 sdk 了,同時(shí)我們使用接口生成代碼,在 go 當(dāng)中可以使用 gomock 非常方便的對(duì)代碼進(jìn)行 mock。
使用 protobuf 定義接口可以解決我們找到 api 文檔之后,文檔不準(zhǔn)確,缺失的問(wèn)題,但是我們應(yīng)該如何找到我們的 api 呢?我們生成出的 api 文件調(diào)用方應(yīng)該如何引用呢?難道我們給每個(gè)調(diào)用方都去開一個(gè)項(xiàng)目的權(quán)限么?那明顯是不太行的,接下來(lái)我們就看看我們 api 該如何管理和組織。
毛老師他們仿照 googleapis/googleapis,istio/api 等知名項(xiàng)目在 b 站內(nèi)部搞了一個(gè) bapis 的倉(cāng)庫(kù)用于同一存放 api 定義文檔,然后通過(guò) ci/cd 生成對(duì)應(yīng)的客戶端代碼放到各個(gè)語(yǔ)言的子倉(cāng)庫(kù)當(dāng)中
工作流程如上圖所示
我們的 api 項(xiàng)目是如何定義的呢?看下圖
隨著應(yīng)用的不斷開發(fā),業(yè)務(wù)的不斷發(fā)展我們的 api 肯定會(huì)不斷的進(jìn)行修改,在修改 api 的時(shí)候考慮 api 的兼容性就會(huì)很重要了,如果我們做了一些破壞性的變更就有可能會(huì)導(dǎo)致依賴我們的服務(wù)或者是客戶端報(bào)錯(cuò),這樣就會(huì)帶來(lái)事故。
一般而言新增都是相對(duì)安全的,但是我們要注意的是新增字段不能改變我們?cè)镜倪壿嫞绻淖兞?api 的邏輯,那就不一定安全了
產(chǎn)品名 | product |
---|---|
應(yīng)用名 | app |
版本號(hào) | v1 |
包名 | product.app.v1 |
目錄結(jié)構(gòu) | api/product/app/v1/xx.proto |
「標(biāo)準(zhǔn)方法」 | 「HTTP 映射」 |
---|---|
List | GET |
Get | GET |
Update | PUT 或者 PATCH |
Create | POST |
Delete | DELETE |
除了標(biāo)準(zhǔn)的也有一些非標(biāo)準(zhǔn)的,例如同步數(shù)據(jù)可能會(huì)用 Sync
等,不過(guò)大部分的 api 應(yīng)該都是標(biāo)準(zhǔn)的
// api/product/app/v1/blog.proto
syntax = "proto3";
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"
}
};
}
}
注意,一般而言我們應(yīng)該為每個(gè)接口都創(chuàng)建一個(gè)自定義的 message,為了后面擴(kuò)展,如果我們用 Empty 的話后續(xù)就沒有辦法新增字段了
先說(shuō)我們當(dāng)前的問(wèn)題,我們一直用的 http 然后我們返回是使用的下面這種格式,然后 http code 統(tǒng)一返回 200
{
"code": 1,
"msg": "xxx",
"data": {}
}
這種做法就存在一個(gè)比較大的問(wèn)題,做監(jiān)控的時(shí)候不太好做,很多現(xiàn)成的東西沒有辦法直接使用,因?yàn)槲覀兌挤祷氐某晒Α⒄?google 的錯(cuò)誤定義,將 http code 和 grpc 錯(cuò)誤碼進(jìn)行映射,返回對(duì)應(yīng)的錯(cuò)誤信息
但是這樣還是不行,因?yàn)檫@樣很多業(yè)務(wù)錯(cuò)誤信息無(wú)法區(qū)分,毛老師他們的 kratos v2 的做法是做了兩層,使用下面的方式進(jìn)行定義
message Status {
// 錯(cuò)誤碼,跟 grpc-status 一致,并且在HTTP中可映射成 http-status
int32 code = 1;
// 錯(cuò)誤原因,定義為業(yè)務(wù)判定錯(cuò)誤碼
string reason = 2;
// 錯(cuò)誤信息,為用戶可讀的信息,可作為用戶提示內(nèi)容
string message = 3;
// 錯(cuò)誤詳細(xì)信息,可以附加自定義的信息列表
repeated google.protobuf.Any details = 4;
}
和我們當(dāng)前的方式差不太多,但是我們是在原來(lái)的基礎(chǔ)上返回了 http code,剩下的字段還是和原來(lái)保持一致
這一點(diǎn)我們之前做的還行,錯(cuò)誤傳播這一部分很容易出的問(wèn)題就是,當(dāng)前服務(wù)直接把上游服務(wù)的錯(cuò)誤給返回了,這樣會(huì)導(dǎo)致一些問(wèn)題:
正確的做法應(yīng)該是把上游錯(cuò)誤信息吞掉,返回當(dāng)前服務(wù)自己定義的錯(cuò)誤信息就可以了。
毛老師課上講的 api 設(shè)計(jì)思路用起來(lái)還是挺爽的,我們已經(jīng)在一個(gè)項(xiàng)目當(dāng)中進(jìn)行了試點(diǎn),cicd 的流程也跑了起來(lái),最爽的一點(diǎn)就是終于不用找接口文檔了,然后還節(jié)省了一些代碼量,我們之前的接口調(diào)用方式都是十分原始的,每個(gè)項(xiàng)目都自己去封裝相關(guān)的 sdk 然后我們對(duì)單元測(cè)試還有要求,http 接口的 mock 是挺麻煩的事情,通過(guò) protobuf 定義接口之后我寫了一個(gè)結(jié)合內(nèi)部網(wǎng)關(guān)的 sdk 代碼生成器,直接生成相關(guān)接口代碼,go interface 的 mock 實(shí)現(xiàn)也在 ci 流程中生產(chǎn)好了,調(diào)用方只需要調(diào)用不同的實(shí)現(xiàn)就行了。下一篇我們就通過(guò)寫一個(gè) 從 proto 生成 gin 代碼的生成器來(lái)看看這個(gè)代碼生成器改如何實(shí)現(xiàn)。
2024年在線市場(chǎng)平臺(tái)的11大最佳支付解決方案
完整指南:如何在應(yīng)用程序中集成和使用ChatGPT API
選擇AI API的指南:ChatGPT、Gemini或Claude,哪一個(gè)最適合你?
用ASP.NET Core 2.1 建立規(guī)范的 REST API — 緩存和并發(fā)
企業(yè)工商數(shù)據(jù)API用哪種?
2024年創(chuàng)建社交媒體帖子的最佳圖像工具API
2024年小型企業(yè)的7個(gè)最佳短信應(yīng)用API
用gin寫簡(jiǎn)單的crud后端API接口
最新LangChain+GLM4開發(fā)AI應(yīng)用程序系列(一):快速入門篇
對(duì)比大模型API的內(nèi)容創(chuàng)意新穎性、情感共鳴力、商業(yè)轉(zhuǎn)化潛力
一鍵對(duì)比試用API 限時(shí)免費(fèi)