API 亂糟糟,專案火葬場?資深工程師的 WordPress REST API 設計聖經 (REST + JSON)

2025/09/15 | WP 開發技巧

API 亂糟糟,專案火葬場?資深工程師的 WordPress REST API 設計聖經 (REST + JSON)

哈囉,我是浪花科技的 Eric。身為一個天天在程式碼海裡打滾的資深工程師,我看過太多讓人血壓飆升的專案了。其中最常見的「災難現場」,莫過於那些沒有章法、隨心所欲打造的 API。端點名稱千奇百怪、回傳的資料格式變幻莫測,今天回傳 A,明天變成 B,搞得前端工程師和串接的夥伴們一個頭兩個大,最後整個專案的維護成本高到爆炸,簡直就是個火葬場。

你可能會想:「WordPress 不就有內建的 REST API 了嗎?為什麼我還需要自己設計?」問得好!WordPress 內建的 API 確實很強大,可以處理文章、頁面、使用者等核心資料。但當你的網站業務邏輯變得複雜,需要處理客製化資料(例如:線上課程進度、電商訂單狀態、會員點數系統),你就勢必得走上打造專屬 API 的這條路。而這條路走得是康莊大道還是崎嶇山路,就取決於你是否掌握了優良的 API 設計原則

今天,我就來當你的領航員,帶你深入理解 RESTful API 的設計精髓,並結合 WordPress 的實戰,教你如何打造出穩定、好維護、讓人一看就懂的專業級 API。別再讓你的 API 成為專案的未爆彈了!

什麼是 RESTful API?為什麼工程師都愛它?

在我們動手寫 code 之前,得先搞懂遊戲規則。REST (Representational State Transfer) 不是一個嚴格的協定,更像是一套「風格指南」或「設計哲學」。遵循這套哲學打造出來的 API,我們就稱之為 RESTful API。它之所以廣受歡迎,是因為它善用了既有的 HTTP 協定,讓整個溝通方式變得非常直觀、有邏輯。

你可以把一個設計良好的 RESTful API 想像成一間井然有序的圖書館:

  • 資源 (Resource): 圖書館裡的每一本書、每一本期刊,都是一個「資源」。在 API 的世界裡,一篇文章、一個商品、一位使用者,都是資源。
  • 唯一的地址 (URI): 每一本書都有獨一無二的編號和位置,例如「文學區/A排/第3層」。在 API 中,每個資源也都有一個唯一的 URL,像是 /products/123 就代表編號 123 的商品。
  • 標準的動作 (HTTP Methods): 你對書本的動作很單純:看書 (GET)、放一本新書上去 (POST)、修改書的內容 (PUT/PATCH)、把書丟掉 (DELETE)。RESTful API 也一樣,用標準的 HTTP 方法來操作資源。
  • 一致的格式 (Representation): 書的內容是用文字和圖片呈現。API 回傳的資源,最常見的就是用 JSON 格式來呈現。

當大家都遵守這套規則時,溝通成本就會大幅降低。前端工程師不用再通靈,猜你這次的 API 端點叫 /get_all_products 還是 /fetchAllProducts,他只需要知道資源是「products」,自然就知道怎麼操作了。

REST API 的四大核心支柱:打造穩固的 API 地基

光說不練假把戲,我們來看看 RESTful API 的幾個關鍵設計原則,這也是判斷一個 API 是否「專業」的照妖鏡。

第一支柱:以「資源」為中心的 URL 命名

這是最多人搞錯的地方!記住一個大原則:URL 裡只放名詞,不放動詞。動詞應該由 HTTP Method 來體現。

  • (NG) 壞設計: /getAllProducts, /createNewProduct, /deleteProductById?id=123
  • (OK) 好設計:
    • GET /products (取得所有商品列表)
    • GET /products/123 (取得 ID 為 123 的商品)
    • POST /products (新增一個商品)
    • PUT /products/123 (完整更新 ID 為 123 的商品)
    • DELETE /products/123 (刪除 ID 為 123 的商品)

你看,好的設計是不是清晰多了?URL 代表你要操作的「資源」,而 HTTP Method 則代表你要執行的「動作」。

第二支柱:善用 HTTP Method (動詞) 表達意圖

HTTP Method 就是你的動詞,請務必正確使用它們:

  • GET: 從伺服器「取得」資源。這個操作是安全的、冪等的(idempotent,執行 N 次結果都一樣),不應該改變伺服器上的任何資料。
  • POST: 在伺服器上「新增」一個資源。例如,註冊新會員、發佈新文章。連續執行兩次 POST,會新增兩個不同的資源。
  • PUT: 「完整取代」伺服器上的一個資源。你需要提供該資源的全部資料,沒提供的欄位可能會被清空。它是冪等的。
  • PATCH: 「部分更新」伺服器上的一個資源。你只需要提供想修改的欄位即可。
  • DELETE: 從伺服器上「刪除」一個資源。它也是冪等的,刪除一次跟刪除一百次的結果都一樣(資源都不見了)。

第三支柱:明確的 HTTP 狀態碼 (Status Code)

不要再只會回傳 200 OK 了!API 的溝通不只是資料本身,還包含「執行的結果狀態」。正確使用狀態碼,可以讓前端開發者更容易處理各種情況。

  • 2xx (成功):
    • 200 OK: 標準的成功請求 (GET, PUT, PATCH)。
    • 201 Created: 資源成功被「新增」(POST)。通常回傳的 body 會包含新資源的資訊和 URL。
    • 204 No Content: 請求成功,但沒有內容需要回傳 (DELETE)。
  • 4xx (客戶端錯誤):
    • 400 Bad Request: 請求的語法有誤,例如 JSON 格式錯誤、缺少必要參數。
    • 401 Unauthorized: 需要身份驗證,但使用者未提供或驗證失敗。
    • 403 Forbidden: 使用者已驗證,但「權限不足」,無法執行此操作。
    • 404 Not Found: 請求的資源不存在。
  • 5xx (伺服器錯誤):
    • 500 Internal Server Error: 伺服器內部發生了未預期的錯誤,這通常是我們的 code 寫炸了。

第四支柱:一致且可預測的 JSON 回應

當 API 成功時,回傳的 JSON 格式應該要有一致的結構。一個囉嗦但好維護的工程師,會把回傳的資料用一個外層結構包起來,方便前端處理。

(NG) 壞設計:

成功時直接回傳陣列:[{...}, {...}]

失敗時回傳物件:{"error": "Something went wrong"}

前端光是要判斷成功還是失敗就得寫一堆 if/else。

(OK) 好設計:

無論成功或失敗,都回傳固定的結構。


// 成功時
{
  "success": true,
  "data": [
    { "id": 1, "name": "商品A" },
    { "id": 2, "name": "商品B" }
  ]
}

// 失敗時
{
  "success": false,
  "error": {
    "code": "invalid_parameter",
    "message": "缺少必要的商品 ID"
  }
}

這樣的結構讓前端可以很簡單地透過 `response.success` 來判斷下一步該怎麼做,程式碼會乾淨很多。

WordPress 實戰:用 register_rest_route 打造你的第一個 API 端點

理論說完了,該來點實際的。在 WordPress 中,我們主要使用 register_rest_route 這個 function 來註冊自訂的 API 端點。通常這段程式碼會放在你的外掛或佈景主題的 functions.php 裡。

假設我們要建立一個 API 來取得一個名為 `course` 的 Custom Post Type 資料,URL 會是 /wp-json/myplugin/v1/courses/<ID>


add_action('rest_api_init', function () {
    register_rest_route('myplugin/v1', '/courses/(?P<id>\d+)', [
        'methods'  => 'GET',
        'callback' => 'myplugin_get_course_details',
        'permission_callback' => '__return_true', // 注意:任何人都可以存取,僅用於公開資料
        'args'     => [
            'id' => [
                'validate_callback' => function($param, $request, $key) {
                    return is_numeric($param);
                }
            ],
        ],
    ]);
});

function myplugin_get_course_details($request) {
    $course_id = $request->get_param('id');
    $post = get_post($course_id);

    // 檢查文章是否存在,且 post type 是否正確
    if (empty($post) || 'course' !== $post->post_type) {
        // 使用 WP_Error 回傳標準的錯誤訊息
        return new WP_Error('rest_not_found', '找不到指定的課程。', ['status' => 404]);
    }

    // 準備要回傳的資料
    $response_data = [
        'id'    => $post->ID,
        'title' => get_the_title($post),
        'content' => apply_filters('the_content', $post->post_content),
        'author'  => get_the_author_meta('display_name', $post->post_author),
    ];

    // 使用 WP_REST_Response 來回傳,可以更好地控制 status code 和 headers
    return new WP_REST_Response($response_data, 200);
}

讓我這個老司機幫你劃一下重點:

  • register_rest_route 第一個參數是 `namespace` (命名空間),通常是 `外掛名稱/版本號`,例如 `myplugin/v1`。這非常重要,可以避免跟其他外掛衝突,同時也實現了版本控制,未來如果你要推出不相容的 API v2,可以直接註冊 `myplugin/v2`,而不會影響到舊的應用。
  • callback 當這個 API 被呼叫時,要執行的 PHP function。
  • permission_callback 權限檢查!這是 API 安全的命脈。範例中的 `__return_true` 代表「公開」,任何人都能存取。對於需要登入或特定權限才能操作的 API,你必須在這裡寫檢查邏輯,例如 `current_user_can(‘edit_posts’)`。
  • WP_Error 當發生錯誤時,請回傳一個 `WP_Error` 物件。WordPress 會自動把它轉換成標準的 JSON 錯誤格式和對應的 HTTP 狀態碼 (如此處的 404)。千萬不要直接 `echo ‘錯誤’` 或 `wp_die()`,那樣非常不專業!

結論:好的 API 設計是送給未來自己最好的禮物

打造一個 API 很容易,但打造一個「好」的 API 卻是一門藝術。它考驗的不只是你的程式技巧,更是你的架構思維和同理心——同理未來需要維護這個 API 的你,以及需要使用這個 API 的夥伴們。

遵循 RESTful 的設計原則,善用資源、HTTP Method 和狀態碼,並保持 JSON 格式的一致性,你就能打造出穩定、可擴展、易於理解的 API。這不僅能大幅提升開發效率,更能讓你的 WordPress 專案提升到一個新的專業層次。別再便宜行事,從今天開始,就把你的 API 當成一個重要的產品來用心設計吧!

如果你在 WordPress 客製化 API、系統串接或是更複雜的企業級應用上遇到了瓶頸,不知道該如何規劃你的 API 架構嗎?別一個人埋頭苦幹了!

歡迎點擊這裡,立即與浪花科技的專家團隊聊聊,讓我們用豐富的實戰經驗,協助你打造出堅實、高效、安全的系統。立即填寫表單,讓我們一起把你的想法變成現實!

延伸閱讀

常見問題 (FAQ)

Q1: 什麼是 REST API?為什麼在 WordPress 開發中這麼重要?

REST (Representational State Transfer) 是一套廣受歡迎的 API 設計風格指南。在 WordPress 中,它讓我們能夠以一種標準化、有邏輯的方式,透過 HTTP 協定來存取和操作網站資料(如文章、商品、會員)。這對於開發前後端分離的網站 (Headless WordPress)、手機 APP、或是與其他第三方服務進行資料交換至關重要,因為它提供了一個清晰、可預測的溝通橋樑。

Q2: 我在設計 API 時,為什麼需要做「版本控制」(例如 /v1/, /v2/)?

版本控制是專業 API 開發中不可或缺的一環。想像一下,你的 API v1 已經有很多地方在使用(例如手機 APP),但現在你需要做一個「破壞性」的改動(例如修改回傳的資料欄位名稱)。如果直接修改 v1,所有正在使用它的 APP 都會崩潰。透過建立一個新的版本,例如 `/wp-json/my-plugin/v2/`,你可以在不影響舊有應用的前提下,開發和推出新的功能,讓舊的應用可以按照自己的步調升級,確保系統的穩定性。

Q3: 如何確保我自訂的 WordPress REST API 是安全的?

API 的安全性至關重要。在 WordPress 中,最關鍵的防線是 `register_rest_route` 函式中的 `permission_callback` 參數。你必須在這個回呼函式中嚴格檢查當前使用者的身份和權限(例如使用 `current_user_can()`)。對於只需要公開讀取的資料,可以設定為公開;但對於任何會修改、新增或刪除資料的操作 (POST, PUT, DELETE),都必須進行嚴格的權限驗證,以防止未經授權的存取和惡意攻擊。

 
立即諮詢,索取免費1年網站保固