電商產品目錄 API 的必備功能:設計指南與最佳實踐
分析哪些功能是必要的,哪些是可選的,以及背後的設計考量
目錄
題目分析
在設計電商產品目錄 API 時,哪些功能是必要的?這個問題看似簡單,但涉及效能、使用者體驗、可維護性等多方面考量。
根據實務經驗,答案是 1、2、3、4、6、7。讓我們深入理解每個功能的重要性。
✅ 必要功能解析
1. Data Format (JSON/XML) - 資料格式
為什麼必要?
現代 API 必須提供標準化的資料格式,讓各種客戶端能夠解析。
實務考量:
- JSON:輕量、易讀、JavaScript 原生支援
- XML:某些企業系統仍在使用
- 建議:預設 JSON,按需支援 XML
實作方式:
Accept: application/json # 客戶端指定
Content-Type: application/json # 伺服器回應
範例回應:
{
"products": [
{
"id": "SKU-12345",
"name": "無線藍牙耳機",
"price": 2990,
"currency": "TWD",
"category": "electronics",
"images": [
"https://cdn.example.com/products/12345-main.jpg"
]
}
]
}
2. Pagination - 分頁
為什麼必要?
產品目錄可能包含數萬件商品,一次載入所有資料會造成:
- 回應時間過長
- 記憶體消耗過大
- 網路頻寬浪費
常見分頁策略:
Offset-based(偏移式):
GET /products?page=2&limit=20
優點:直觀、容易實作
缺點:深度分頁效能差
Cursor-based(游標式):
GET /products?cursor=eyJpZCI6MTAwfQ&limit=20
優點:效能穩定、適合即時資料
缺點:無法跳頁
最佳實踐回應:
{
"products": [...],
"pagination": {
"page": 2,
"limit": 20,
"total": 1543,
"totalPages": 78,
"hasNext": true,
"hasPrev": true,
"links": {
"first": "/products?page=1&limit=20",
"prev": "/products?page=1&limit=20",
"next": "/products?page=3&limit=20",
"last": "/products?page=78&limit=20"
}
}
}
3. Filtering - 過濾
為什麼必要?
用戶需要快速找到想要的產品,過濾功能是核心體驗。
常見過濾維度:
- 類別:category=electronics
- 價格範圍:min_price=1000&max_price=5000
- 品牌:brand=apple,samsung
- 評分:min_rating=4
- 庫存狀態:in_stock=true
- 多重屬性:color=black&size=L
實作範例:
GET /api/v1/products?
category=electronics&
sub_category=headphones&
brand=sony,apple&
min_price=1000&
max_price=5000&
min_rating=4&
features=wireless,noise-cancelling
# 複雜過濾使用 POST
POST /api/v1/products/search
{
"filters": {
"category": ["electronics"],
"price": {
"min": 1000,
"max": 5000
},
"attributes": {
"color": ["black", "white"],
"connectivity": ["bluetooth"]
}
}
}
4. Sorting - 排序
為什麼必要?
不同用戶有不同的瀏覽偏好,排序讓他們快速找到想要的商品。
常見排序選項:
- 價格:price_asc, price_desc
- 上架時間:date_desc(最新優先)
- 熱門度:popularity
- 評分:rating_desc
- 折扣幅度:discount_desc
實作方式:
GET /products?sort=price_asc
GET /products?sort=-price # 負號表示降序
GET /products?sort=brand,price # 多重排序
進階排序邏輯:
// 相關性排序(搜尋時)
GET /products/search?q=wireless+earphone&sort=relevance
// 個人化排序
GET /products?sort=recommended
Headers: Authorization: Bearer <user-token>
6. Caching Headers - 快取標頭
為什麼必要?
產品資訊更新頻率相對較低,適當的快取可以:
- 減少伺服器負載
- 提升回應速度
- 節省頻寬成本
# 回應標頭範例
HTTP/1.1 200 OK
Cache-Control: public, max-age=300 # 快取 5 分鐘
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
Last-Modified: Wed, 21 Oct 2024 07:28:00 GMT
Vary: Accept-Encoding, Accept
# 條件請求
GET /products/12345
If-None-Match: "33a64df551425fcc55e4d42a148795d9f25f89d4"
# 如果沒變化,返回 304 Not Modified
快取策略設計:
產品列表頁:
Cache-Control: public, max-age=300 # 5 分鐘
產品詳情頁:
Cache-Control: public, max-age=3600 # 1 小時
搜尋結果:
Cache-Control: private, max-age=60 # 1 分鐘,個人化
即時價格:
Cache-Control: no-cache # 不快取
7. API Versioning - API 版本控制
為什麼必要?
API 會隨業務演進,版本控制確保:
- 向後相容性
- 平滑升級路徑
- 多版本並存
版本控制策略:
1. URL 路徑版本:
/api/v1/products
/api/v2/products
優點:清晰明確
缺點:URL 變更
2. 請求標頭版本:
GET /api/products
API-Version: 2.0
優點:URL 不變
缺點:不夠直觀
3. 內容協商:
Accept: application/vnd.myapi.v2+json
優點:符合 REST 原則
缺點:複雜
版本遷移範例:
// v1 回應(將被棄用)
{
"product_id": 12345,
"product_name": "無線耳機"
}
// v2 回應(新版本)
{
"id": "SKU-12345",
"name": "無線耳機",
"deprecated_fields": {
"product_id": 12345,
"product_name": "無線耳機"
},
"_links": {
"self": "/api/v2/products/SKU-12345"
}
}
❌ 可選功能分析
5. User Authentication - 使用者驗證
為什麼是可選的?
產品目錄通常是公開資訊:
- 訪客也能瀏覽商品
- SEO 需要爬蟲能訪問
- 降低使用門檻
需要認證的場景:
- B2B 電商(會員專屬價格)
- 個人化推薦
- 瀏覽歷史記錄
- 收藏清單存取
實作方式:
# 公開端點
GET /api/v1/products # 無需認證
# 個人化端點
GET /api/v1/products/recommended
Authorization: Bearer <token>
8. Real-time Inventory Updates - 即時庫存更新
為什麼是可選的?
對於產品目錄 API,即時庫存並非必要:
- 瀏覽階段不需要精確庫存
- 即時更新成本高
- 只在結帳時需要準確庫存
庫存顯示策略:
瀏覽階段(目錄 API):
- "有貨" / "缺貨" / "即將到貨"
- 快取 5-10 分鐘
加入購物車:
- 檢查基本庫存
- 預留機制
結帳階段:
- 即時庫存檢查
- 分散式鎖
- 庫存預留確認
🏗️ 完整的產品目錄 API 設計
API 端點設計
# 產品列表
GET /api/v1/products
?category=electronics
&brand=apple,samsung
&min_price=1000
&max_price=5000
&sort=price_asc
&page=2
&limit=20
# 產品詳情
GET /api/v1/products/{product_id}
# 產品搜尋
GET /api/v1/products/search?q=wireless+earphone
# 相關產品
GET /api/v1/products/{product_id}/related
# 產品評價
GET /api/v1/products/{product_id}/reviews
完整回應範例
{
"data": {
"products": [
{
"id": "SKU-12345",
"name": "Apple AirPods Pro",
"description": "主動式降噪無線耳機",
"price": {
"amount": 7990,
"currency": "TWD",
"original": 8990,
"discount": {
"amount": 1000,
"percentage": 11
}
},
"category": {
"id": "cat-101",
"name": "耳機",
"path": "電子產品 > 音訊設備 > 耳機"
},
"brand": {
"id": "brand-apple",
"name": "Apple"
},
"images": [
{
"url": "https://cdn.example.com/products/12345-1.jpg",
"alt": "產品正面圖",
"type": "primary"
}
],
"attributes": {
"color": ["白色", "黑色"],
"connectivity": "藍牙 5.0",
"battery_life": "4.5 小時"
},
"rating": {
"average": 4.5,
"count": 1234
},
"availability": {
"status": "in_stock",
"quantity": "10+" // 模糊化的庫存
},
"created_at": "2024-01-15T08:00:00Z",
"updated_at": "2024-10-20T10:30:00Z"
}
]
},
"pagination": {
"page": 2,
"limit": 20,
"total": 1543,
"totalPages": 78
},
"filters": {
"applied": {
"category": ["electronics"],
"brand": ["apple", "samsung"]
},
"available": {
"brands": [
{"id": "apple", "name": "Apple", "count": 234},
{"id": "samsung", "name": "Samsung", "count": 189}
],
"priceRange": {
"min": 99,
"max": 99999
}
}
},
"sorting": {
"current": "price_asc",
"available": ["relevance", "price_asc", "price_desc", "rating", "date"]
},
"meta": {
"version": "1.0",
"generated_at": "2025-01-10T10:00:00Z"
}
}
📈 效能優化建議
1. 查詢優化
資料庫索引:
- category_id + brand + price(複合索引)
- created_at(時間排序)
- rating(評分排序)
查詢策略:
- 使用資料庫的全文搜尋
- ElasticSearch 用於複雜搜尋
- 預先計算的統計資料
2. 快取層級
CDN 層:
- 靜態資源(圖片)
- 熱門查詢結果
Redis 層:
- 產品基本資訊
- 分類樹結構
- 篩選器選項
應用層:
- 記憶體快取
- 查詢結果快取
🎯 關鍵要點總結
設計良好的電商產品目錄 API 應該包含:
✅ 核心功能:
- 標準資料格式(JSON/XML)
- 分頁機制防止過載
- 靈活的過濾功能
- 多樣的排序選項
- 智慧的快取策略
- 清晰的版本控制
⚡ 可選功能:
- 認證(視業務需求)
- 即時庫存(結帳時再處理)
記住:產品目錄 API 的目標是讓用戶快速找到想要的商品,而不是提供所有可能的功能。保持簡單、快速、可靠,才是好的 API 設計。