如何建立 REST API:設計、安全與部署
要建立 REST API,先列出你的 App 管理的資源(例如使用者、訂單、預約),為每個資源設定網址,例如 /orders 和 /orders/{id},並用 HTTP 方法表示動作:GET 讀取、POST 建立、PATCH 更新、DELETE 刪除。回傳帶有有意義狀態碼的 JSON,驗證每一筆輸入,在伺服器端要求身份驗證並檢查每筆資料的權限,列表資料則要分頁。接著為 API 撰寫文件,並在 HTTPS 之後部署。
本指南涵蓋設計決策、一組實作的路由範例、給 AI 應用程式建構工具的提示詞,以及造成安全漏洞的常見錯誤。如果你對 API 還不熟悉,請先閱讀 什麼是 API。
何時需要 REST API
- 你的網頁前端需要從伺服器儲存與讀取資料
- 行動 App、合作夥伴或自動化工具需要存取你的資料
- 其他服務會向你發送事件(webhook)
- 你要把工作分給前端與後端團隊
REST 是最常見的風格,但不是唯一的選擇。REST 與 GraphQL 的比較說明何時單一、彈性的查詢端點更適合。
先設計:資源與路由
先寫下你的 App 中的名詞,以及人們會對它們做什麼事。以一個簡單的預約 App 為例:
| 方法 | 路由 | 功能 | 成功狀態碼 |
|---|---|---|---|
GET | /api/bookings | 列出呼叫者的預約(分頁) | 200 |
POST | /api/bookings | 建立預約 | 201 |
GET | /api/bookings/{id} | 取得單筆預約 | 200 |
PATCH | /api/bookings/{id} | 變更部分欄位 | 200 |
DELETE | /api/bookings/{id} | 取消預約 | 204 |
GET | /api/health | 供監控使用的健康檢查 | 200 |
這些對應到建立、讀取、更新與刪除,請參閱 什麼是 CRUD。值得遵循的慣例:
- URL 使用複數名詞,不用動詞:用
/bookings,不要用/getBookings。 - 巢狀結構只保留一層,且只在能釐清從屬關係時使用:
/bookings/{id}/notes。 - 非 CRUD 的動作可以設計成子資源:
POST /bookings/{id}/cancel比神秘的 PATCH 更清楚。 - 欄位命名保持一致,例如各處都用
created_at。
狀態碼與錯誤
使用標準 HTTP 狀態碼,讓客戶端不必解析文字就能知道發生了什麼:
| 狀態碼 | 意義 | 使用時機 |
|---|---|---|
| 200 | OK | 讀取或更新成功 |
| 201 | Created | POST 建立了資源 |
| 204 | No Content | 成功但沒有需要回傳的內容 |
| 400 | Bad Request | 輸入未通過驗證 |
| 401 | Unauthorized | 未登入或權杖無效 |
| 403 | Forbidden | 已登入但沒有權限 |
| 404 | Not Found | 資源不存在,或不應讓呼叫者知道它存在 |
| 409 | Conflict | 重複資料,或時段已被預訂 |
| 429 | Too Many Requests | 達到速率限制 |
| 500 | Server Error | 你這一端發生錯誤 |
錯誤回應請使用一致的 JSON 格式,例如 {"error": {"code": "slot_taken", "message": "該時段已無法預約。"}},並且絕對不要在回應中包含堆疊追蹤或資料庫錯誤。
選項與取捨
| 決策 | 簡單的選擇 | 替代方案 |
|---|---|---|
| API 放在哪裡 | 你的網頁框架中的 API 路由 | 獨立的 API 服務,適合多個客戶端或不同語言 |
| 身份驗證 | 你自己的網頁 App 使用 Session Cookie | 行動 App 與第三方使用權杖(Bearer Token 或 API 金鑰) |
| 分頁 | ?page=2&limit=20 | 游標式分頁(?after=...),對大型且持續變動的列表較穩定 |
| 版本管理 | 在有外部使用者之前不做 | 當其他人開始依賴時,在路徑加上 /v1/ |
| 文件 | 列出路由的 README | OpenAPI 規格,工具可據此產生互動式文件與客戶端程式碼 |
逐步進行
- 列出資源與路由,如上所示,並包含每個路由可由誰呼叫。
- 建立資料模型,設計資料庫中需要的欄位與關聯。
- 先建立讀取路由,再建立新增、更新與刪除。
- 在每個寫入操作上驗證輸入,使用結構描述(schema)函式庫:必填欄位、型別、長度、允許的值。拒絕未知欄位。
- 加入身份驗證,接著加入每筆資料的授權:讀取
/bookings/42時,必須確認預約 42 屬於呼叫者,而不只是確認有人已登入。 - 所有列表都要分頁,並限制每頁的最大筆數。
- 對登入與高成本路由進行速率限制。請參閱速率限制。
- 只有在其他網域的瀏覽器必須呼叫 API 時才設定 CORS,並明確列出那些來源。如何修正 CORS 錯誤說明你會遇到的錯誤。
- 為每個路由撰寫文件與測試,包含失敗的情境。
- 部署時將機密資訊放在環境變數中,並啟用 HTTPS、日誌與健康檢查。
給 AI 建構工具的提示詞
建立骨架:
為預約功能建立 REST API,包含以下路由:GET /api/health、GET /api/bookings(分頁,每頁最多 50 筆)、POST /api/bookings、GET /api/bookings/:id、PATCH /api/bookings/:id、DELETE /api/bookings/:id。資料儲存在我們的資料庫。請使用結構描述函式庫驗證請求內容,並拒絕未知欄位。錯誤請以 {"error": {"code", "message"}} 的 JSON 格式回傳,並使用正確的狀態碼(400、401、403、404、409)。機密資訊請存放在環境變數中。
安全性:
每個預約路由都要求登入。每次讀取、更新與刪除時,都要在伺服器端確認該預約屬於目前使用者;若不屬於,回傳 404。絕不接受請求內容中的使用者 ID 或角色。對 POST /api/bookings 以每位使用者每分鐘 20 次的頻率限制。伺服器端記錄錯誤,但不要回傳堆疊追蹤。
文件:
為這些路由撰寫 OpenAPI 描述,並提供一份簡短的 README,附上每個路由的請求與回應範例。
測試你的 API
請從前端之外進行測試,因為攻擊者一定會這麼做:
- 每個路由在有效輸入下都能運作,並回傳文件所述的格式與狀態碼
- 缺少或無效的欄位會回傳 400,並附上清楚的訊息
- 每個受保護的路由在沒有權杖時都會回傳 401
- 使用者 A 以 ID 請求使用者 B 的資料時,會得到 404 或 403
- 列表有分頁;過大的
limit會被限制 - 重複或衝突的建立請求會回傳 409,而不是 500
- 超過速率限制會回傳 429
- 錯誤回應不包含堆疊追蹤、SQL 或機密資訊
- CORS 只允許你打算允許的來源
常見錯誤
- 只檢查登入,沒有檢查擁有權。 這是 API 最常見的漏洞:任何已登入的使用者只要改變 ID,就能讀取任何資料。
- 信任客戶端。 請求內容中的價格、角色與使用者 ID 都可以被竄改。
- 回傳整筆資料庫紀錄。 密碼雜湊與內部欄位會外洩。請明確選擇每個回應要包含哪些欄位。
- 列表沒有上限。 一次請求所有資料會拖慢整個 App。
- 以
200 OK回傳內含錯誤訊息的內容。 客戶端與監控無法判斷請求其實失敗了。 - 在使用 Cookie 的 API 上將 CORS 設為允許所有來源。
- 沒有健康檢查或日誌,導致你是從使用者那裡得知服務中斷。
若要進行更全面的上線前檢查,請參閱 AI 建構 App 的安全檢查清單。
在 Mythex 中建立 REST API
你可以請 Mythex 為你的 App 建立 API,或建立獨立的服務。文件中的 REST API 後端食譜提供了一段起始提示詞:說明你的框架與路由、要求清楚的 JSON 錯誤格式、將機密資訊存放在環境變數中,並包含 Dockerfile。Node、Python、C#、Java 等容器化後端都透過 Dockerfile 發佈,Mythex 會從「發佈」處理部署(API 後端)。一個專案可以同時執行網站與 API 伺服器,並可在預覽中切換兩者。請將金鑰儲存為專案機密;如果 API 需要資料庫,請在對話中提出需求。若要為 API 安排背景工作,請參閱如何執行背景工作。
常見問題
什麼是 REST API?
REST API 是程式透過 HTTP 存取你 App 資料的方式。每一類資料都是一個資源,有自己的網址,例如 /orders,再透過標準方法對它操作:GET 讀取、POST 建立、PATCH 或 PUT 更新、DELETE 刪除。資料通常以 JSON 格式傳送。
我應該用哪種語言建立 REST API?
選你或團隊能夠維護的語言即可。Node.js 搭配 Express 或 Fastify、Python 搭配 FastAPI,以及 C# 或 Java 的框架都很適合。路由、狀態碼、驗證與身份驗證的設計原則,比語言本身更重要。
如何保護 REST API 的安全?
每個非公開的路由都要求身份驗證,在伺服器端確認呼叫者是否有權存取特定資料,驗證所有輸入,使用 HTTPS,限制請求頻率,並將機密資訊存放在環境變數中。絕不要信任客戶端傳來的 ID 或角色。
REST API 一定要獨立的後端嗎?
不一定。Next.js 等框架可以在提供頁面的同時提供 API 路由。當多個客戶端(網頁、行動裝置、合作夥伴)都要使用,或需要獨立的語言或擴展能力時,才適合另外建立獨立的 API 服務。