Last Updated on 2024-06-02 by Clay
介紹
RESTful 設計風格(Representational State Transfer, REST)是一種用於設計網路應用程式的架構風格。它遵守著讓網路應用程式更加簡潔、可擴展和易於維護的準則去設計。
以下是 RESTful 設計風格的核心概念和原則:
核心概念
- 資源 (Resources):
- 資源是網絡中的任何實體,可以是用戶、圖片、文件等
- 每個資源都由一個 URI (Uniform Resource Identifier) 唯一標識
- 表現形式 (Representations):
- 資源可以有多種表現形式,例如 JSON、XML、HTML 等
- 客戶端通過這些表現形式與資源進行互動
- 狀態轉換 (State Transfer):
- 客戶端與服務器之間的互動是無狀態的,每個請求都包含所有必要的信息
- 通過 HTTP 方法(如 GET、POST、PUT、DELETE)進行狀態轉換
基本原則
- 無狀態 (Statelessness):
- 每個請求都應該是獨立的,不依賴於之前的請求
- 服務器不會在請求之間保留客戶端的狀態
- 統一接口 (Uniform Interface):
- 使用標準的 HTTP 方法和狀態碼
- 資源的表示應該是帶有意義的,以便客戶端能夠理解和使用它們
- 可擴展性 (Scalability):
- 通過無狀態的請求和分層系統設計來提高系統的可擴展性
- 可緩存性 (Cacheability):
- 服務器應明確標識哪些資源是可緩存的,以提高性能
- 分層系統 (Layered System):
- 客戶端不需要知道直接與最終服務器通信,請求可能通過多個中介層
- 這種分層設計有助於提高系統的可擴展性和安全性
- 按需編碼 (Code on Demand)(Optional):
- 服務器可以將可執行代碼(如 JavaScript)傳遞給客戶端,讓客戶端在運行時執行
HTTP 方法
講到 RESTful 原則設計出的 APIs,就順便條列一下基本的 HTTP 請求方法:
- GET:
- 用於檢索、取得資源
- 是 read-only 操作,不會改變資源的狀態
- POST:
- 用於創建新的資源
- 通常會在服務器創建一個新資源並返回其 URI
- PUT:
- 用於更新現有資源
- 如果資源不存在,可以創建一個新的(簡單來說,跟 insert + update 組合成的 upsert 操作很像)
- DELETE:
- 用於刪除資源
- PATCH:
- 用於部分更新資源
遵守著以上原則,基本上我們就可以設計出簡單、可擴展性、可維護性高且靈活的 APIs。接下來我們就來實際操作一次。
實際案例
以下是使用 Python FastAPI 所啟動的一個簡單的 RESTful APIs 接口,涵蓋了基本的 CRUD 操作。
from typing import List, Optional
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
import uvicorn
app = FastAPI()
# Define resource model
class Item(BaseModel):
id: int
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
# Simulated database
items_db = []
# POST - Create resource
@app.post("/items/", response_model=Item)
def create_item(item: Item):
for db_item in items_db:
if db_item.id == item.id:
raise HTTPException(status_code=400, detail="Item already exists")
items_db.append(item)
return item
# GET - Get the all resources
@app.get("/items/", response_model=List[Item])
def read_items():
return items_db
# GET - Get the specific resource
@app.get("/items/{item_id}", response_model=Item)
def read_item(item_id: int):
for item in items_db:
if item.id == item_id:
return item
raise HTTPException(status_code=404, detail="Item not found")
# PUT - Update the resource
@app.put("/items/{item_id}", response_model=Item)
def update_item(item_id: int, updated_item: Item):
for index, item in enumerate(items_db):
if item.id == item_id:
items_db[index] = updated_item
return updated_item
raise HTTPException(status_code=404, detail="Item not found")
# PUT - Update part of resource
@app.patch("/items/{item_id}", response_model=Item)
def partial_update_item(item_id: int, item_update: dict):
for item in items_db:
if item.id == item_id:
if "name" in item_update:
item.name = item_update["name"]
if "description" in item_update:
item.description = item_update["description"]
if "price" in item_update:
item.price = item_update["price"]
if "tax" in item_update:
item.tax = item_update["tax"]
return item
raise HTTPException(status_code=404, detail="Item not found")
# Delete - delete the resource
@app.delete("/items/{item_id}")
def delete_item(item_id: int):
for index, item in enumerate(items_db):
if item.id == item_id:
del items_db[index]
return {"detail": "Item deleted"}
raise HTTPException(status_code=404, detail="Item not found")
if __name__ == "__main__":
uvicorn.run("app:app", host="0.0.0.0", port=8000, reload=True)
CURL 終端機請求範例
在開啟 FastAPI 服務後,可以使用以下的 HTTP 方法去請求資源。以下的方法因為 WordPress 現在不給放完整的 curl
指令,所以我只紀錄了後段,要測試只需要在最前方加上 curl
指令即可。
創建資源 (POST)
-X POST "http://127.0.0.1:8000/items/" -H "Content-Type: application/json" -d '{"id": 1, "name": "Item1", "description": "A sample item", "price": 10.0, "tax": 1.0}'
獲取所有資源 (GET)
-X GET "http://127.0.0.1:8000/items/"
獲取單個資源 (GET)
-X GET "http://127.0.0.1:8000/items/1"
更新資源 (PUT)
-X PUT "http://127.0.0.1:8000/items/1" -H "Content-Type: application/json" -d '{"id": 1, "name": "Updated Item", "description": "Updated description", "price": 20.0, "tax": 2.0}'
部分更新資源 (PATCH)
-X PATCH "http://127.0.0.1:8000/items/1" -H "Content-Type: application/json" -d '{"name": "Partially Updated Item", "price": 15.0}'
刪除資源 (DELETE)
-X DELETE "http://127.0.0.1:8000/items/1"
這些命令展示了如何使用 curl 與 FastAPI 構建的 RESTful API 進行互動。