# Ch 08. RPC 與 Query-Based API 設計
Restful 之外最常被用到的 API 風格是 RPC (Remote Procedure Call, 遠端程序呼叫) 及 Query-Based API (查詢式 API)
## 什麼是 RPC API
RPC 的概念是執行遠端的程式碼,Server 給 Client 一個清單,讓 Client 知道 Server 有這些程式可以跑,以及每個程式各自的 Request 及 Response 結構。
RPC 架構下,Client 及 Server 的程式是緊密綁定的,一旦 Server 改變,Client 也會跟著改變
:::info
原本以為 Client / Server 是緊密綁定這件事蠻唬爛的,但搜尋了一下文件發現,在 .net 的範例中,可以透過 grpc tool 直接產生一個 cs file,後端需要透過繼承這個 cs 來實作這個 gRPC 的 endpoint
不過感覺跟 Client / Server 還是感覺可以分開實作,他頂多跟 Restful 一樣,可能異動 Server 後,Client 也要跟著異動
:::
#### gRPC vs Restful API

Ref. https://pjchender.dev/golang/grpc-getting-started/
### gRPC
gRPC 是 Google 發起的協議,Kubernetes 內部也是透過 gRPC 來做資訊的交換。gRPC 用 HTTP/2 作為底層的通訊協議,並且使用 Protocol Buffers (ProtoBuf) 來當作 Request 及 Response 的資料格式,並且利用 HTTP/2 的雙向串流特性來實現 Client/Server 的互動
#### gRPC 資料交換機制

通常 ProtoBuf 的格式如下:
```protobuf
syntax = "proto3";
import "google/protobuf/timestamp.proto";
option csharp_namespace = "grpc_chat";
package chat;
service Chatroom {
rpc Join(stream SpeakRequest) returns (stream BroadcastMessage);
}
message SpeakRequest {
string uid = 1;
string name = 2;
string message = 3;
}
message BroadcastMessage {
string speaker = 1;
google.protobuf.Timestamp time = 2;
string message = 3;
}
```
### RPC 優缺點
優點
* RPC 效能較好
* 因為遵守 ProtoBuf 定義的格式來開發,因此不用特別思考 Endpoint 要如何設計,靠工具 Generate 出來後,直接實作內容就好了
缺點
* 格式難以閱讀
* 無法指定媒體類型 (media type)
* 如果 Client 是瀏覽器的話,需要安裝其他的套件並強制使用他的指定的驗證機制才能與 API Endpont 進行互動 (無感)
### RPC API 規格
一樣先定義出來 Request 及 Response,並且照著 ProtoBuf 風格填寫

最後就可以產生出一份 ProtoBuf 的文件

## 什麼是 Query-Based API
Query-Based API 是以查詢為基礎的 API,讓 Client 可以自己決定要如何查詢資料,並且自己決定要拿那些資料,而且也有分頁及過濾的能力
Query-Based API 也可以一次把跟該資源有相關的資料一次性取回來,把他的父子資源都一起取回來,因此可以省下多次的查詢往返,而目前較流行的方案是 OData 及 GraphQL
### OData
OData 是由 OASIS 管理的標準化協議,他是以 HTTP 及 Json 為基礎的 Query-Based API,跟 Restful 很接近,且也以 **"資源"** 為核心概念
通常 OData 也會實作 Hypermedia 的相關資源或連結
#### 書上提供的 OData 範例

:::success
但我還是覺得 OData 不好維護,如果專案不夠大型,資料不夠多元,用 OData 會讓服務變得相對難維護
:::
### GraphQL
由 Facebook 在 2012 年開發,2015 年公開,目標是讓 Client 可以自行決定回應的粒度及資料深度
GraphQL 只有用到 Get 及 Post 而已,具體的內容以 GraphQL 的查詢語言撰寫,也可以在查詢內對服務下某些運算或邏輯
#### 書上提供的 GraphQL 範例

GraphQL 可以做為既有 Rest API 的前端,並且解析完 Request 後再轉給後端的 REST API 取得資料後,在彙整回去給前端
GraphQL 在設計上是以單一 Endpoint 與 Client 互動,因此 GraphQL 也難以用到 HTTP 的既有特性
### Query-Based API 設計流程
1. 為所有資源設計圖譜結構

2. 設計 Query 及 Mutation (異動) 操作
Safe => Query
Idempotent / Unsafe => Mutation
3. 撰寫 API 規格文件

###### tags: `Web API 設計原則:API與微服務傳遞價值之道` `Book`