Chuyển đến nội dung chính

第 5 堂課:API 設計大師班 — REST、GraphQL 與 gRPC

REST、GraphQL 和 gRPC 的詳細比較:用例、效能、權衡。 RESTful API 最佳實務、GraphQL 架構設計、具有 Protocol Buffers 的 gRPC。 API 版本控制策略和向後相容性。

🏗️ 建築 — 第 5 課 第 5 堂課:API 設計大師班 — REST、 GraphQL 和 gRPC

微服務與微前端系統設計-從基礎到生產

第 2 部分:設計微服務後端

亞洲開發網

簡介

API 是服務之間以及後端和前端之間的合約。選擇正確的API風格和良好的設計決定了微服務架構的成敗。本文深入探討了 3 種最受歡迎的 API 樣式,並說明如何為每個用例選擇正確的 API 樣式。


1. REST API — 預設選擇

1.1 RESTful 最佳實踐

基於資源的 URL:

GET    /api/v1/products              → List products
GET    /api/v1/products/{id}         → Get product
POST   /api/v1/products              → Create product
PUT    /api/v1/products/{id}         → Update product
PATCH  /api/v1/products/{id}         → Partial update
DELETE /api/v1/products/{id}         → Delete product
GET    /api/v1/products/{id}/reviews → Nested resource

分頁(基於遊標):

{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTAwfQ==",
    "has_more": true,
    "total": 1500
  }
}

標準錯誤回應:

{
  "error": {
    "code": "PRODUCT_NOT_FOUND",
    "message": "Product with id '123' not found",
    "details": []
  }
}

1.2 API 版本控制策略

戰略範例優點缺點
網址路徑/api/v1/products明確、易於路由網址更改
標題Accept: application/vnd.api.v2+json乾淨的網址隱藏
查詢參數/api/products?version=2簡單凌亂

推薦: URL 路徑版本控制 — 簡單、清晰、易於在 API 閘道上路由。

1.3 何時使用 REST

  • 第三方公共API
  • 簡單的CRUD操作
  • 關鍵快取(HTTP 本機快取)
  • 熟悉的團隊,成熟的工具

2. GraphQL-靈活的查詢

2.1 為什麼微前端要用 GraphQL?

每個微前端都需要來自同一服務的不同的資料:

# Product MFE (cần đầy đủ thông tin)
query ProductDetail {
  product(id: "123") {
    id, name, description, price
    images { url, alt }
    reviews { rating, comment, user { name } }
    relatedProducts { id, name, price }
  }
}

# Cart MFE (chỉ cần tên + giá)
query CartItem {
  product(id: "123") {
    id, name, price, thumbnail
  }
}

→ GraphQL 解決了過度獲取(REST 返回太多)和不足獲取(REST 需要調用許多端點)的問題。

2.2 模式設計最佳實踐

type Product {
  id: ID!
  name: String!
  slug: String!
  price: Money!
  images: [Image!]!
  category: Category!
  reviews(first: Int, after: String): ReviewConnection!
}

type Money {
  amount: Float!
  currency: Currency!
}

type ReviewConnection {
  edges: [ReviewEdge!]!
  pageInfo: PageInfo!
}

2.3 何時使用 GraphQL

  • 前端需要資料取得的靈活性
  • 多個前端客戶端需要不同的數據
  • BFF層或API網關聚合
  • 複雜的嵌套資料關係

3. gRPC — 高效能內部

3.1 協定緩衝區

// product.proto
syntax = "proto3";

service ProductService {
  rpc GetProduct(GetProductRequest) returns (Product);
  rpc ListProducts(ListProductsRequest) returns (stream Product);
  rpc CreateProduct(CreateProductRequest) returns (Product);
}

message Product {
  string id = 1;
  string name = 2;
  double price = 3;
  repeated string image_urls = 4;
}

message GetProductRequest {
  string id = 1;
}

3.2 gRPC 優勢

  • ~比 JSON 序列化(二進位格式)快 10 倍
  • HTTP/2:多重化、標頭壓縮
  • 強型別:產生的程式碼,編譯時檢查
  • 雙向流:即時資料流

3.3 何時使用 gRPC

  • 服務到服務通訊(僅限內部)
  • 高吞吐量、低延遲要求
  • 串流資料(即時更新、日誌)
  • 多語言:Go、Java、Python、Node.js 的程式碼生成

4.決策矩陣

標準休息GraphQLgRPC
主要用途外部 API、CRUD前端查詢服務到服務
性能好好優
快取HTTP 原生複雜(持久查詢)手冊
學習曲線低中高
前端友善是的非常否(需要代理)
串流媒體SSE/WebSocket訂閱本地
工具優好成長
瀏覽器支援本地本地需要 gRPC-Web

4.1 電商平台建議

Client → Shell/MFE:     GraphQL (flexible, typed)
MFE → BFF/Gateway:      REST hoặc GraphQL
Gateway → Services:      REST (simple CRUD) + gRPC (high-perf)
Service → Service:       gRPC (internal) + Events (async)

總結

  • REST:外部API和簡單CRUD的預設選擇
  • GraphQL:非常適合微前端 - 減少過度/不足的獲取
  • gRPC:服務到服務之王 — 快速、類型化、串流媒體
  • 實務上:使用所有 3 種方法的組合來實現正確的用例

下一篇文章: 第 6 課:服務間通訊 — 同步、非同步與事件驅動