
開始接觸後端開發後,很快就會遇到一個核心問題:前端送來的需求,後端要怎麼接收、處理,再把結果傳回去?
以 Todo List 為例,使用者打開頁面時,前端需要向後端取得目前有哪些待辦事項;新增 Todo 時,也需要把輸入的內容送到後端處理。這些資料交換不會自己發生,而是需要一套前後端都能理解的溝通方式,而這就是 API 會出現的地方。
API 的全名是 Application Programming Interface(應用程式介面),可以先理解成:
讓不同程式按照約定彼此溝通的介面。
假設前端想取得所有 Todo,可以向後端發出:
GET /todos
後端收到 Request 後,處理資料,再回傳:
[
{
"id": 1,
"title": "學習 Node.js",
"completed": false
}
]
前端取得 Response 後,就能把 Todo 顯示到畫面上。
API 的重點就在「約定」。前端只需要知道 Request 要怎麼送、需要提供哪些資料,以及 Server 會回傳什麼結果,不需要知道後端使用哪一種資料庫、資料怎麼查詢,或內部執行了哪些程式邏輯。換句話說,API 就像是前端與後端之間事先訂好的溝通方式。
一個 API 通常不會只有一個功能,例如 Todo List 可能需要查看所有 Todo、查看某一筆 Todo、新增、修改或刪除資料。
因此後端會提供不同的 API 存取位置,讓 Client 知道 Request 應該送到哪裡,這些對外提供服務的位置通常稱為 Endpoint。
例如:
/todos
可以表示 Todo 相關的資源,而:
/todos/1
則可以表示 ID 為 1 的 Todo。
實際開發時,也常會看到:
/todos/:id
這裡的 :id 代表一個可以變動的值,因此實際呼叫時可能會變成:
/todos/1
/todos/2
/todos/10
Endpoint 可以幫助我們指出這次 Request 想存取哪一類資源,或是哪一筆特定資料。不過只知道 Endpoint 還不夠,因為同一個 /todos 可以用來取得資料,也可以用來新增資料,這時就需要搭配 HTTP Method,表示這次想進行什麼操作。
HTTP Method 可以理解成 Client 想對資源進行的操作,常見的 Method 有:
| Method | 用途 |
|---|---|
| GET | 取得資料 |
| POST | 新增資料 |
| PUT | 修改整筆資料,通常傳送完整資料 |
| PATCH | 修改部分資料,只傳送需要修改的欄位 |
| DELETE | 刪除資料 |
例如:
GET /todos
代表取得 Todo 列表。
POST /todos
代表新增一筆 Todo。
DELETE /todos/1
則代表刪除 ID 為 1 的 Todo。
因此在描述一支 API 時,通常會把 Method + Endpoint 一起看,才能知道 Client 到底想對哪一個資源進行什麼操作。
當 API 數量越來越多,如果每個人都按照自己的方式命名,很容易變得混亂。例如有人可能會寫:
/getTodos
/createTodo
/deleteTodo
另一個人則可能寫:
/todoList
/addTodo
/removeTodo
功能可能一樣,但命名方式不同。當專案規模變大、API 越來越多時,就會增加理解與維護成本。
REST 是一種軟體架構風格,而依照 REST 概念設計的 API,通常稱為 RESTful API。REST 本身包含不少設計原則,不過初學階段可以先掌握一個常見的概念:
URL 用來表示資源,HTTP Method 用來表示想對資源進行的操作。
例如 Todo 是一種資源,可以統一使用:
/todos
再搭配不同 Method:
| Method | Endpoint | 用途 |
|---|---|---|
| GET | /todos |
取得 Todo 列表 |
| POST | /todos |
新增一筆 Todo |
| GET | /todos/:id |
取得指定 Todo |
| PATCH | /todos/:id |
修改指定 Todo |
| DELETE | /todos/:id |
刪除指定 Todo |
這樣就不需要另外設計:
/getTodos
/createTodo
/updateTodo
/deleteTodo
整體會更一致,也比較容易直接從 Method 和 Endpoint 判斷這支 API 的用途。
其中:
POST /todos
雖然使用的是代表 Todo 集合的 /todos,但它的意思是:在 Todo 集合中建立一筆新的 Todo。
使用 GET 取得資料時,通常不會透過 Request Body 傳遞資料;當 Client 想新增或修改資料時,則常會把資料放進 Request Body。
例如要新增一筆 Todo:
POST /todos
Request Body 可以帶上:
{
"title": "學習 API",
"completed": false
}
Web API 很常使用 JSON(JavaScript Object Notation) 來傳遞這類結構化資料。JSON 看起來和 JavaScript Object 很像,例如 JavaScript Object:
const todo = {
title: "學習 API",
completed: false
};
JSON 則會寫成:
{
"title": "學習 API",
"completed": false
}
兩者看起來很接近,但並不是同一個東西。JavaScript Object 是 JavaScript 程式中的資料結構,而 JSON 是一種文字格式,也有自己的語法規則,例如 JSON 的 key 必須使用雙引號。
因此 Client 可以把資料轉換成 JSON 格式後,放進 Request Body 傳給 Server;Server 處理完成後,也很常使用 JSON 格式作為 Response Body 回傳結果。
Server 處理完 Request 後,除了回傳資料之外,也會透過 HTTP Status Code 告訴 Client 這次操作的結果。
常見的 Status Code 有:
| Status Code | 常見情境 |
|---|---|
| 200 OK | 成功取得或修改資料 |
| 201 Created | 成功建立資料 |
| 204 No Content | 成功處理,但沒有 Response Body |
| 400 Bad Request | Request 格式或內容有問題 |
| 401 Unauthorized | 尚未通過身分驗證 |
| 403 Forbidden | 已經知道身分,但沒有操作權限 |
| 404 Not Found | 找不到指定資源 |
| 500 Internal Server Error | Server 發生未預期的錯誤 |
也可以先從 Status Code 的第一個數字理解:
2xx → Request 成功處理
4xx → Client 送出的 Request 有問題
5xx → Server 處理 Request 時發生問題
例如新增 Todo:
POST /todos
Request Body:
{
"title": "學習 API",
"completed": false
}
如果建立成功,Server 可能回傳:
201 Created
以及:
{
"id": 3,
"title": "學習 API",
"completed": false
}
這樣 Client 不只拿到新增完成後的資料,也能透過 Status Code 判斷這次操作是否成功。
理解 API 的基本結構後,接下來可以直接使用 Node.js 建立一支最簡單的 API。
建立一個 server.js,並加入以下程式碼:
const http = require("http");
const server = http.createServer(function (req, res) {
console.log(req.method, req.url);
if (req.url === "/todos" && req.method === "GET") {
res.writeHead(200, {
"Content-Type": "application/json"
});
res.end(
JSON.stringify({
message: "Hello API!"
})
);
return;
}
res.writeHead(404, {
"Content-Type": "application/json"
});
res.end(
JSON.stringify({
message: "Not Found"
})
);
});
server.listen(3030, function () {
console.log("Server running at http://localhost:3030");
});
在終端機執行:
node server.js
在瀏覽器開啟:
http://localhost:3030/todos
就會收到:
{
"message": "Hello API!"
}
這段程式使用 Node.js 內建的 http 模組建立 HTTP Server。當 Request 送進來時,req 代表 Server 收到的 Request,而 res 則用來建立並送出 Response。
程式會先透過 req.url 和 req.method 判斷這次 Request 是否為:
GET /todos
如果條件符合,就會執行:
res.writeHead(200, {
"Content-Type": "application/json"
});
res.writeHead() 用來設定 Response 的 Status Code 與 Header。這裡的 200 代表 Request 處理成功,而 Content-Type: application/json 則是在告訴 Client,這次 Response Body 回傳的是 JSON 格式的資料。
Response Body 則透過 res.end() 回傳:
res.end(
JSON.stringify({
message: "Hello API!"
})
);
因為程式中建立的是 JavaScript Object,所以先使用 JSON.stringify() 將它轉換成符合 JSON 格式的字串,再透過 res.end() 將內容送回 Client,並結束這次 Response。
這裡的 return 則是用來結束目前這次 Request 的處理。因為 GET /todos 已經成功回傳 Response,如果沒有停止程式繼續往下執行,就會再次執行後面的 404 Response。
如果 Request 不符合 GET /todos,例如開啟:
http://localhost:3030/test
程式就會往下執行:
res.writeHead(404, {
"Content-Type": "application/json"
});
res.end(
JSON.stringify({
message: "Not Found"
})
);
並回傳:
{
"message": "Not Found"
}
因此這支 API 已經包含了前面介紹過的幾個元素:
Client
│
│ GET /todos
▼
Node.js Server
│
│ Response
▼
Status Code → 200
Header → Content-Type: application/json
Body → {"message":"Hello API!"}
到這裡,前面提到的 Endpoint、HTTP Method、Request、Response、Status Code、Header 和 JSON,也真正和 Node.js 程式碼連接起來了。
目前我們只有處理 GET /todos,如果之後還要加入 POST /todos、PATCH /todos/:id 或 DELETE /todos/:id,就需要繼續透過 req.url 和 req.method 判斷不同的 Request。隨著 API 數量增加,使用 Node.js 原生的 http 模組就會需要自己處理越來越多路由與 Request 細節,這也是之後會使用 Express 的原因之一。
API 建立完成後,不需要等前端畫面做好才開始測試。只要有工具可以發出 HTTP Request,就能直接確認 API 是否按照預期運作,常見的方式有瀏覽器、curl 和 Postman。
如果只是測試 GET API,可以直接在瀏覽器輸入:
http://localhost:3030/todos
瀏覽器會向這個網址發出 GET Request,因此很適合快速確認 API 是否正常回傳資料。目前這支 API 會回傳:
{
"message": "Hello API!"
}
不過瀏覽器網址列不方便設定 Request Body、Headers,或自由切換 POST、PATCH、DELETE 等 Method,因此適合的情境比較有限。
curl 可以直接從終端機發送 HTTP Request,例如測試目前的 API:
curl http://localhost:3030/todos
就可以看到 Server 回傳:
{"message":"Hello API!"}
curl 也可以指定不同的 Method、Header 或 Request Body。例如未來實作:
POST /todos
就可以使用:
curl -X POST http://localhost:3030/todos \
-H "Content-Type: application/json" \
-d '{"title":"學習 API","completed":false}'
其中 -X POST 用來指定 HTTP Method,-H 用來設定 Header,-d 則代表要傳送的資料。
目前這支 API 還沒有實作 POST /todos,所以這段只是示範 curl 可以如何發送帶有 Method、Header 和 Request Body 的 HTTP Request。
Postman 是一個圖形化的 HTTP Client,可以直接設定 Method、URL、Headers 和 Body,再送出 Request。
測試目前的 API 可以按照以下步驟操作:
GET
http://localhost:3030/todos
送出後,就可以查看 Server 回傳的 Status Code、Headers 與 Response Body。
Response Body 會是:
{
"message": "Hello API!"
}
Status Code 則會看到:
200 OK
之後開始實作 POST、PATCH 或 DELETE API 時,就可以透過 Postman 切換不同 Method,並設定 Headers 與 Request Body 進行測試。
例如測試 POST API 時,可以在 Body 中選擇:
raw → JSON
再輸入:
{
"title": "學習 API",
"completed": false
}
選擇 JSON 後,Postman 通常也會自動加入:
Content-Type: application/json
可以到 Headers 分頁確認實際送出了哪些 Header。

簡單整理這幾種測試 API 的方式:
| 方式 | 適合情境 |
|---|---|
| 瀏覽器 | 快速測試 GET API |
| curl | 從終端機快速發送 Request |
| Postman | 測試不同 Method、Body 與 Headers |
使用哪一種工具不是最重要的,真正重要的是知道:API 可以獨立測試,不需要等前端完成後,才確認後端是否正常。
Web API 的基本概念其實可以整理成一件事:Client 按照約定發出 Request,Server 接收並處理,再透過 Response 回傳結果。
Endpoint 決定 Request 要存取哪一個資源,HTTP Method 表示想對資源進行什麼操作,Request Body 可以攜帶資料,JSON 常用來交換結構化內容,而 Status Code 則負責告訴 Client 最後的處理結果。
RESTful API 則提供了一套較一致的 API 設計方式,讓不同 Endpoint 的命名與操作規則更容易理解。
到這裡,我們已經不只是知道 Server 可以接收 Request,而是開始理解一支 API 是怎麼被設計、呼叫與測試的。不過前面的 Node.js 範例也可以看出,目前如果想根據不同 Endpoint 和 HTTP Method 執行不同程式,就需要自己判斷 req.url、req.method,並處理更多細節。
接下來開始使用 Express 時,就會發現這些原本需要自己處理的流程,可以用更簡潔、更有結構的方式完成。