[ADP-360] 資源擴展
指導原則
預設情況下不應(SHOULD NOT)返回獨立的子資源
httpGET /orders/{orderId} HTTP/1.1 { "orderId": "12345", "customerName": "John Doe", "totalPrice": 100.00, "orderedAt": "2024-07-05" }
預期該資源有項目和運送作為獨立的子資源(例如,每個資源都有自己的id)
INFO
為了優化效能,子資源(如項目和運送)應該作為獨立資源進行維護,並擁有自己的識別碼。這種方法能夠實現高效的資源管理和擴展性。
雖然你可以設計一個 API 在單一回應中返回所有相關資源,但這必須在 API 規範中明確說明。本原則提供了一個標準化機制,用於擴展預設回應中未包含的相關資源。
應(SHOULD)支持通過
embed
查詢參數嵌入子資源httpGET /orders/{order-id}?embed=(items) { "orderId": "12345", "customerName": "John Doe", "totalPrice": 100.00, "items": [ { "orderItemId": "1", "productId": "987", "productName": "Widget", "quantity": 2, "price": 25.00 }, { "orderItemId": "2", "productId": "654", "productName": "Gadget", "quantity": 1, "price": 50.00 } ], "shipping": { "shippingId": "56789", "carrier": "UPS", "trackingNumber": "1Z9999999999999999", "estimatedDeliveryDate": "2024-07-10" } }
應(SHOULD)使用標準 JSON 結構來嵌入資源,並使用清晰的屬性命名
httpGET /orders/{order-id}?embed=(items,shippings) { "id": "uuid-...", "orderId": "12345", "customerName": "John Doe", "totalPrice": 100.00, "items": [ { "orderItemId": "1", "productId": "987", "productName": "Widget", "quantity": 2, "price": 25.00, "links": { "self": "/products/987" } }, { "orderItemId": "2", "productId": "654", "productName": "Gadget", "quantity": 1, "price": 50.00, "links": { "self": "/products/654" } } ], "shipping": { "shippingId": "56789", "carrier": "UPS", "trackingNumber": "1Z9999999999999999", "estimatedDeliveryDate": "2024-07-10", "links": { "self": "/shippings/56789" } } }
應(SHOULD)使用 Link 標頭根據 RFC 8288 進行資源間的導航
httpGET /orders/12345?embed=(items,shippings) HTTP/1.1 HTTP/1.1 200 OK Content-Type: application/json Link: </orders/12345>; rel="self", </orders/12345/items>; rel="items", </orders/12345/shippings>; rel="shippings" { "id": "uuid-...", "orderId": "12345", "customerName": "John Doe", "totalPrice": 100.00, "items": [...], "shipping": {...} }
應(SHOULD)在 API 規範中記錄可用的嵌入選項
應(SHOULD)限制嵌入資源的深度以防止性能問題
應(SHOULD)實現適當的錯誤處理以應對無效的嵌入請求
OpenAPI 3.1.0 示例
yaml
openapi: 3.1.0
info:
title: 訂單 API
version: 1.0.0
paths:
/orders/{orderId}:
get:
summary: 獲取訂單
parameters:
- name: embed
in: query
description: 嵌入相關資源
schema:
type: array
items:
type: string
enum:
- items
- shippings
collectionFormat: csv
responses:
'200':
description: 成功回應
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
components:
schemas:
Order:
type: object
properties:
orderId:
type: string
customerName:
type: string
totalPrice:
type: number
orderedAt:
type: string
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
shipping:
$ref: '#/components/schemas/Shipping'
OrderItem:
type: object
properties:
orderItemId:
type: string
productId:
type: string
productName:
type: string
quantity:
type: integer
price:
type: number
Shipping:
type: object
properties:
shippingId:
type: string
carrier:
type: string
trackingNumber:
type: string
estimatedDeliveryDate:
type: string
參考
設計參考
- https://opensource.zalando.com/restful-api-guidelines/#158
- https://api.otto.de/portal/guidelines/rest-guidelines/resources
更新紀錄
2025-03-07
:Add the consideration description.