GET /users
獲取指定用戶:
GET /users/1
創(chuàng)建用戶:

POST /users
{
"name": "John",
"age": 30
}
更新用戶:
PUT /users/1
{
"name": "John",
"age": 31
}
刪除用戶:
DELETE /users/1

它的優(yōu)點(diǎn)在于:

  1. 易于理解和簡(jiǎn)單
  2. 具有良好的可擴(kuò)展性
  3. 可以跨平臺(tái)使用
  4. 允許集成緩存機(jī)制
  5. 支持非常高效的數(shù)據(jù)交換

標(biāo)準(zhǔn)接口

RESTful API中,我們使用標(biāo)準(zhǔn)的接口比如 /users 來操作資源,然后通過過濾條件或資源標(biāo)識(shí)來指定操作哪些資源。例如:

獲取所有用戶:  GET /users
創(chuàng)建一個(gè)產(chǎn)品: POST /users?type=product
更新一條訂單: PUT /users/1?type=order
刪除一篇文章: DELETE /users/2?type=post

這樣設(shè)計(jì)的好處是接口簡(jiǎn)單易用,客戶端可以通過一套標(biāo)準(zhǔn)接口來訪問不同類型的資源,只需要在請(qǐng)求中提供必要的過濾條件或資源標(biāo)識(shí)。

HATEOAS

HATEOAS是代表”Hypermedia As The Engine Of Application State”的首字母縮寫。它是RESTful API的一個(gè)重要原則,意思是應(yīng)用狀態(tài)應(yīng)驅(qū)動(dòng)由超媒體來定義和控制。也就是說,RESTful API應(yīng)該提供一系列超鏈接來連接相關(guān)資源,并通過這些鏈接來定義客戶端的工作流程與導(dǎo)航方式。客戶端不需要事先知道這些鏈接,只需要與API進(jìn)行交互,并根據(jù)獲得的鏈接來獲取更多信息或調(diào)整狀態(tài)。一個(gè)典型的例子是Github的API。例如,當(dāng)我們獲取一個(gè)用戶資源時(shí):

{
"login": "octocat",
"id": 1,
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
"gravatar_id": "",
"url": "https://api.github.com/users/octocat",
"html_url": "https://github.com/octocat",
"followers_url": "https://api.github.com/users/octocat/followers",
"following_url": "https://api.github.com/users/octocat/following{/other_user}",
"gists_url": "https://api.github.com/users/octocat/gists{/gist_id}",
"starred_url": "https://api.github.com/users/octocat/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/octocat/subscriptions",
"organizations_url": "https://api.github.com/users/octocat/orgs",
"repos_url": "https://api.github.com/users/octocat/repos",
"events_url": "https://api.github.com/users/octocat/events{/privacy}",
"received_events_url": "https://api.github.com/users/octocat/received_events",
"type": "User",
"site_admin": false
}

這個(gè)用戶資源提供了許多鏈接,分別指向:

  1. API響應(yīng)中提供其他相關(guān)資源的鏈接
  2. 客戶端可以通過這些鏈接來獲取更多信息或改變狀態(tài)
  3. 客戶端不需要事先 hardcoded 這些鏈接,只需要?jiǎng)討B(tài)的根據(jù)獲得的鏈接來導(dǎo)航

RPC接口的設(shè)計(jì)

設(shè)計(jì)微服務(wù)RPC接口時(shí),可以遵循RESTful的理念和規(guī)范,使RPC接口易于理解和使用,客戶端可以像調(diào)用REST API一樣調(diào)用這些接口。
比如 設(shè)計(jì)一個(gè)商城系統(tǒng),有訂單,用戶,支付,商品,系統(tǒng)內(nèi)部采用微服務(wù)架構(gòu),使用gRPC協(xié)議,具體的設(shè)計(jì)可以如下:

1. 資源導(dǎo)向

定義訂單服務(wù)OrderService,用戶服務(wù)UserService,商品服務(wù)ProductService等。

2. 使用服務(wù)方法對(duì)應(yīng)CRUD

訂單服務(wù):

CreateOrder(Order)  創(chuàng)建訂單,對(duì)應(yīng)POST /orders
GetOrder(OrderId) 獲取訂單,對(duì)應(yīng)GET /orders/{id}
UpdateOrder(Order) 更新訂單,對(duì)應(yīng)PUT /orders/{id}
DeleteOrder(OrderId) 刪除訂單,對(duì)應(yīng)DELETE /orders/{id}

用戶服務(wù):

CreateUser(User) 創(chuàng)建用戶,對(duì)應(yīng)POST /users
GetUser(UserId) 獲取用戶,對(duì)應(yīng)GET /users/{id}
UpdateUser(User) 更新用戶,對(duì)應(yīng)PUT /users/{id}
DeleteUser(UserId) 刪除用戶,對(duì)應(yīng)DELETE /users/{id}

3. 統(tǒng)一接口格式

每個(gè)服務(wù)使用如下格式定義接口

service OrderService {
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse) {}
rpc GetOrder(GetOrderRequest) returns (GetOrderResponse) {}
// 其他方法...
}

message CreateOrderRequest {
// 請(qǐng)求參數(shù)
}

message CreateOrderResponse {
// 返回結(jié)果
}

4. 無狀態(tài)

服務(wù)端不會(huì)儲(chǔ)存客戶端狀態(tài),每次請(qǐng)求必須包含所有必要信息。

5. Get接口返回全部信息

返回全部信息可以防止不同需求需要獲取某個(gè)資源(比如訂單)不同字段信息從而每次新定義一個(gè)接口造成接口數(shù)量急劇膨脹泛濫降低可維護(hù)性。如果某些面向客戶端接口(協(xié)議)只需要特定字段,在網(wǎng)關(guān)層進(jìn)行信息裁剪。

6.錯(cuò)誤處理

?在RESTful API中,我們常用HTTP狀態(tài)碼表示錯(cuò)誤,并在響應(yīng)體中返回詳細(xì)的錯(cuò)誤信息。在gRPC接口中,我們可以返回非空的錯(cuò)誤信息來表示錯(cuò)誤:

// 錯(cuò)誤信息
message Error {
int err_code = 1; //錯(cuò)誤碼
string message = 2; // 錯(cuò)誤描述
}

// 創(chuàng)建訂單接口
rpc CreateOrder(CreateOrderRequest) returns (CreateOrderResponse) {}

// 錯(cuò)誤響應(yīng)
message CreateOrderResponse {
Error error = 1; // 包含錯(cuò)誤信息的Error消息
}

客戶端調(diào)用此接口,如果返回的CreateOrderResponse中包含error信息,就表示調(diào)用失敗,可以獲取error消息中的詳細(xì)失敗原因。

7. 元數(shù)據(jù)(Labels)

?在RESTful API中,我們可以使用請(qǐng)求頭中的元數(shù)據(jù)來提供調(diào)用相關(guān)的上下文信息。在gRPC接口中,我們可以在請(qǐng)求消息和響應(yīng)消息中包含label字段:

message CreateOrderRequest {
// 請(qǐng)求參數(shù)...

// 元數(shù)據(jù)
map<string, string> labels = 10;
}

message CreateOrderResponse {
// 返回結(jié)果...

// 元數(shù)據(jù)
map<string, string> labels = 10;
}

labels是一個(gè)字符串到字符串的映射,可以包含諸如:

這樣設(shè)計(jì)的RPC接口具有如下優(yōu)點(diǎn):

  1. 資源導(dǎo)向,易于理解和使用
  2. 服務(wù)方法對(duì)應(yīng)CRUD操作,調(diào)用者很容易理解 
  3. 標(biāo)準(zhǔn)接口格式,各個(gè)接口看上去很規(guī)范整齊
  4. 借鑒了RESTful的理念,幾乎可以當(dāng)作RPC版的RESTful API來調(diào)用

所以,總體來說,這是一種模型比較清晰的RPC接口設(shè)計(jì)思路,可以讓RPC的接口設(shè)計(jì)更加符合微服務(wù)架構(gòu)下的實(shí)踐,也更易于被人理解和使用。

本文章轉(zhuǎn)載微信公眾號(hào)@吃瓜技術(shù)派

上一篇:

從 API 設(shè)計(jì)開始,了解一下 Golang 的新框架 Twirp

下一篇:

Windows遠(yuǎn)端線程執(zhí)行任意API的設(shè)計(jì)與實(shí)現(xiàn)
#你可能也喜歡這些API文章!

我們有何不同?

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

多API并行試用

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

查看全部API→
??

熱門場(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)