Skip to main content

什麼是 RESTful API

REST(Representational State Transfer)是一種基於 HTTP 協議的設計架構,用來讓前端和後端透過標準化的方式進行資料交換。RESTful API 通常使用 HTTP 方法(如 GET、POST、PUT、DELETE)來操作資源(resources),並以 JSON 格式傳輸資料。


RESTful API 設計原則

在設計 RESTful API 時,有以下幾個核心原則,這些原則能讓 API 易於理解和使用:

  1. 以資源為中心

    • 每個 API 都代表一個「資源」(resource),例如「使用者」、「訂單」或「產品」。

    • 資源用名詞表示,並使用複數形式。例如:/users 表示所有使用者,/users/123 表示 ID 為 123 的使用者。

  2. 使用標準 HTTP 方法

    • GET:取得資源(例如:取得所有使用者 /users 或單一使用者 /users/123)。

    • POST:創建新資源(例如:新增使用者 /users)。

    • PUTPATCH:更新現有資源(例如:更新使用者資料 /users/123)。

    • DELETE:刪除資源(例如:刪除使用者 /users/123)。

  3. 使用有意義的 URL 路徑

    • URL 應該清楚表達資源的層次結構。例如:/users/123/orders 表示 ID 為 123 的使用者的所有訂單。

    • 避免在 URL 中使用動詞,例如不應該用 /getUsers 或 /deleteUser。

  4. 使用 HTTP 狀態碼

    • 200 OK:請求成功。

    • 201 Created:成功創建資源。

    • 400 Bad Request:請求格式錯誤。

    • 404 Not Found:資源不存在。

    • 500 Internal Server Error:伺服器錯誤。

  5. 保持無狀態(Stateless)

    • 每個 API 請求都必須包含所有必要資訊,伺服器不應儲存客戶端的狀態。例如,認證資訊需要每次請求都帶上(通常用 JWT token)。
  6. 提供一致的資料格式

    • 通常使用 JSON 格式回傳資料,並確保回應結構一致。例如:

      {
      "data": {
      "id": 123,
      "name": "John Doe",
      "email": "john@example.com"
      },
      "message": "Success"
      }

RESTful API 設計範例

假設我們要設計一個簡單的「使用者管理系統」API,包含以下功能:

  • 取得所有使用者

  • 取得單一使用者

  • 新增使用者

  • 更新使用者

  • 刪除使用者

以下是對應的 API 設計:

HTTP 方法URL 路徑功能回應狀態碼範例
GET/users取得所有使用者200 OK
GET/users/:id取得單一使用者200 OK, 404 Not Found
POST/users新增使用者201 Created, 400 Bad Request
PUT/users/:id更新使用者資料200 OK, 404 Not Found
DELETE/users/:id刪除使用者204 No Content, 404 Not Found

範例 API 回應(JSON 格式)

  • GET /users:

    {
    "data": [
    { "id": 1, "name": "John Doe", "email": "john@example.com" },
    { "id": 2, "name": "Jane Smith", "email": "jane@example.com" }
    ],
    "message": "Users retrieved successfully"
    }
  • POST /users(請求 body):

    {
    "name": "John Doe",
    "email": "john@example.com"
    }
  • POST /users(回應):

    {
    "data": {
    "id": 3,
    "name": "John Doe",
    "email": "john@example.com"
    },
    "message": "User created successfully"
    }

在 React 中與 RESTful API 互動

以下我會提供一個完整的 React 範例,展示如何使用 fetch 或 axios 與上述的 RESTful API 互動。我們會建立一個簡單的使用者管理介面,包含:

  • 顯示所有使用者清單

  • 新增使用者表單

  • 刪除使用者按鈕

步驟 1:設置 React 專案

如果你還沒有 React 專案,可以用以下指令建立一個:

npx create-react-app user-management
cd user-management
npm start

步驟 2:安裝 axios(非必要,但推薦)

axios 是一個方便的 HTTP 請求工具,比原生的 fetch 更簡單易用。安裝方式:

npm install axios

步驟 3:建立 API 服務層

為了讓程式碼更乾淨,我們會建立一個專門處理 API 請求的檔案 api.js。

檔案:src/api.js

import axios from "axios";

// 設定 API 的基礎 URL(假設後端 API 在這個地址)
const API_URL = "http://localhost:3000/api";

// 取得所有使用者
export const getUsers = async () => {
try {
const response = await axios.get(`${API_URL}/users`);
return response.data;
} catch (error) {
console.error("取得使用者失敗:", error);
throw error;
}
};

// 取得單一使用者
export const getUserById = async (id) => {
try {
const response = await axios.get(`${API_URL}/users/${id}`);
return response.data;
} catch (error) {
console.error(`取得使用者 ${id} 失敗:`, error);
throw error;
}
};

// 新增使用者
export const createUser = async (userData) => {
try {
const response = await axios.post(`${API_URL}/users`, userData);
return response.data;
} catch (error) {
console.error("新增使用者失敗:", error);
throw error;
}
};

// 更新使用者
export const updateUser = async (id, userData) => {
try {
const response = await axios.put(`${API_URL}/users/${id}`, userData);
return response.data;
} catch (error) {
console.error(`更新使用者 ${id} 失敗:`, error);
throw error;
}
};

// 刪除使用者
export const deleteUser = async (id) => {
try {
const response = await axios.delete(`${API_URL}/users/${id}`);
return response.data;
} catch (error) {
console.error(`刪除使用者 ${id} 失敗:`, error);
throw error;
}
};

步驟 4:建立 React 元件

我們會在 App.js 中建立一個簡單的使用者管理介面,包含使用者清單和新增使用者的表單。

檔案:src/App.js

import React, { useState, useEffect } from "react";
import { getUsers, createUser, deleteUser } from "./api";
import "./App.css";

function App() {
// 儲存使用者清單的狀態
const [users, setUsers] = useState([]);
// 儲存表單輸入的狀態
const [formData, setFormData] = useState({
name: "",
email: "",
});
// 儲存錯誤訊息
const [error, setError] = useState("");

// 當元件載入時,取得所有使用者
useEffect(() => {
fetchUsers();
}, []);

// 取得使用者清單的函數
const fetchUsers = async () => {
try {
const response = await getUsers();
setUsers(response.data); // 假設回應格式為 { data: [...] }
} catch (err) {
setError("無法取得使用者清單");
}
};

// 處理表單輸入變化的函數
const handleInputChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};

// 處理新增使用者的函數
const handleSubmit = async (e) => {
e.preventDefault();
try {
await createUser(formData);
setFormData({ name: "", email: "" }); // 清空表單
fetchUsers(); // 重新取得使用者清單
} catch (err) {
setError("新增使用者失敗");
}
};

// 處理刪除使用者的函數
const handleDelete = async (id) => {
try {
await deleteUser(id);
fetchUsers(); // 重新取得使用者清單
} catch (err) {
setError("刪除使用者失敗");
}
};

return (
<div className="App">
<h1>使用者管理</h1>

{/* 新增使用者表單 */}
<form onSubmit={handleSubmit}>
<div>
<label>姓名:</label>
<input
type="text"
name="name"
value={formData.name}
onChange={handleInputChange}
required
/>
</div>
<div>
<label>電子郵件:</label>
<input
type="email"
name="email"
value={formData.email}
onChange={handleInputChange}
required
/>
</div>
<button type="submit">新增使用者</button>
</form>

{/* 錯誤訊息 */}
{error && <p style={{ color: "red" }}>{error}</p>}

{/* 使用者清單 */}
<h2>使用者清單</h2>
<ul>
{users.map((user) => (
<li key={user.id}>
{user.name} ({user.email})
<button onClick={() => handleDelete(user.id)}>刪除</button>
</li>
))}
</ul>
</div>
);
}

export default App;

步驟 5:添加簡單的 CSS

為了讓介面看起來更整潔,我們在 App.css 中加入一些基本樣式。

檔案:src/App.css

.App {
max-width: 600px;
margin: 0 auto;
padding: 20px;
}

form {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 20px;
}

form div {
display: flex;
flex-direction: column;
gap: 5px;
}

input {
padding: 8px;
font-size: 16px;
}

button {
padding: 8px;
background-color: #007bff;
color: white;
border: none;
cursor: pointer;
}

button:hover {
background-color: #0056b3;
}

ul {
list-style: none;
padding: 0;
}

li {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px;
border-bottom: 1px solid #ccc;
}

步驟 6:測試你的應用程式

  1. 確保你的後端 API 正在運行(例如在本機的 http://localhost:3000/api)

  2. 執行 npm start 啟動 React 應用程式。

  3. 打開瀏覽器,前往 http://localhost:3000 ,你應該會看到一個簡單的使用者管理介面:

    • 表單可以輸入姓名和電子郵件來新增使用者。

    • 使用者清單會顯示所有使用者,並有刪除按鈕。


常見問題與解決方式

  1. 後端 API 尚未準備好怎麼辦?
    如果你還沒有後端 API,可以使用像 JSONPlaceholder 這樣的免費假 API 來測試。只需要將 API_URL 改為 https://jsonplaceholder.typicode.com 即可。例如:

    const API_URL = "https://jsonplaceholder.typicode.com";
  2. 如何處理認證(例如 JWT)?
    如果 API 需要認證,通常會在請求的標頭(headers)中加入 token。例如:

    export const getUsers = async (token) => {
    try {
    const response = await axios.get(`${API_URL}/users`, {
    headers: { Authorization: `Bearer ${token}` },
    });
    return response.data;
    } catch (error) {
    console.error("取得使用者失敗:", error);
    throw error;
    }
    };
  3. 如何處理載入狀態?
    你可以新增一個 isLoading 狀態來顯示「載入中」的提示:

    const [isLoading, setIsLoading] = useState(false);

    const fetchUsers = async () => {
    setIsLoading(true);
    try {
    const response = await getUsers();
    setUsers(response.data);
    } catch (err) {
    setError("無法取得使用者清單");
    } finally {
    setIsLoading(false);
    }
    };

    // 在 JSX 中顯示載入狀態
    {
    isLoading && <p>載入中...</p>;
    }

總結

  • RESTful API 設計:遵循資源導向、標準 HTTP 方法、清晰的 URL 結構和 JSON 格式。

  • React 實作:使用 axios 或 fetch 與 API 互動,將 API 請求封裝在獨立的服務層,並透過 React 的狀態管理顯示資料。

  • 程式碼完整性:我提供了完整的程式碼範例,包括 API 服務層、React 元件和 CSS 樣式,應該能讓你輕鬆跟著操作。