API 總是噴錯?資深工程師教你用 JSON Schema 打造 WordPress 堅不可摧的資料驗證層

2026/01/15 | API 串接與自動化, WP 開發技巧, 全端與程式開發

JSON Schema:WordPress API 堅固資料契約的藍圖

厭倦了前端送來的「髒資料」導致 API 頻繁噴錯嗎?資深工程師 Eric 帶您擺脫傳統 PHP 中深層巢狀的 if-else 驗證地獄,迎接 JSON Schema 的宣告式力量!Schema 不僅是 API 的結構藍圖與活文件,更能強制要求嚴謹的型別,讓您的 WordPress REST API 像個堅不可摧的堡壘。本文將深入探討如何在 WordPress 核心中優雅實作 Schema,實現「Schema First」的設計哲學。立即升級您的資料驗證層,確保系統安全且高效運行!

需要專業協助?

聯絡浪花專案團隊 →

API 總是噴錯?資深工程師教你用 JSON Schema 打造 WordPress 堅不可摧的資料驗證層

嗨,我是 Eric,浪花科技的資深工程師。今天我們來聊聊一個讓後端工程師常常「牙起來」的話題:API 資料驗證

你一定遇過這種狀況:前端送來的 JSON 少了欄位,或者是明明該傳數字的地方傳了字串(還是 "null" 這種字串,眼神死),結果你的 PHP 程式碼直接噴出 500 Internal Server Error,然後客戶氣沖沖地跑來問為什麼網站掛了。

在 WordPress 開發 REST API 時,很多工程師習慣用一堆 if ( !isset($_POST['email']) ) 或者 empty() 來檢查。說實話,這種寫法不僅醜,而且維護起來簡直是地獄。如果你的資料結構有三層巢狀迴圈,你的 if-else 大概會縮排到螢幕外面去。

今天這篇文章,我要帶大家進入 JSON Schema 的世界。這不只是為了驗證,更是為了「設計」出結構嚴謹、自我描述的 API。我們會講到如何在 WordPress 中優雅地實作它,拒絕髒資料進入你的資料庫。

什麼是 JSON Schema?為什麼你需要它?

簡單來說,JSON Schema 就是 JSON 資料的「藍圖」或「契約」。它本身也是一段 JSON,用來描述:「我的資料應該長什麼樣子」。

在工程團隊協作(特別是前後端分離)時,JSON Schema 有幾個巨大的好處:

  • 自動化驗證:你不需要手寫幾十行檢查程式碼,只需要定義好規則,驗證器(Validator)會幫你搞定。
  • 即時文件化:Schema 本身就是最好的文件。Swagger (OpenAPI) 基本上就是基於 JSON Schema 產生的。
  • 前後端解耦:後端先把 Schema 開出來,前端依照 Schema 產生假資料(Mock Data)開發,大家不用互相等。
  • 強型別思維:雖然 PHP 是弱型別,但透過 Schema,我們可以強制要求 API 介面的型別嚴謹度。

WordPress REST API 中的 Schema 設計

WordPress 核心的 REST API 其實已經內建了對 Schema 的支援,但很多開發者都忽略了 register_rest_route 中的 schema 參數,只專注在 callback 上。這是非常可惜的。

一個好的 API 設計,應該是「Schema First」。我們先定義資料結構,再寫邏輯。

基礎範例:定義一個產品提交的 Endpoint

假設我們要開一支 API 讓外部系統寫入產品資料,我們希望資料結構包含:產品名稱(字串)、價格(數字)、庫存(整數)、以及標籤(字串陣列)。

如果是傳統寫法,你可能在 callback 裡寫滿了檢查邏輯。但在 JSON Schema 思維下,我們這樣做:

add_action( 'rest_api_init', function () {
    register_rest_route( 'roamer/v1', '/products', array(
        'methods'  => 'POST',
        'callback' => 'roamer_create_product',
        'permission_callback' => function() { return current_user_can('edit_posts'); },
        'args'     => array(), // 這裡我們通常留空,改用 schema 定義
        'schema'   => 'roamer_product_schema',
    ) );
} );

function roamer_product_schema() {
    return array(
        '$schema'              => 'http://json-schema.org/draft-04/schema#',
        'title'                => 'product',
        'type'                 => 'object',
        'properties'           => array(
            'name' => array(
                'description'  => '產品名稱',
                'type'         => 'string',
                'minLength'    => 3,
                'maxLength'    => 100,
            ),
            'price' => array(
                'description'  => '產品價格',
                'type'         => 'number',
                'minimum'      => 0,
            ),
            'stock_qty' => array(
                'description'  => '庫存數量',
                'type'         => 'integer',
                'minimum'      => 0,
            ),
            'tags' => array(
                'description'  => '產品標籤',
                'type'         => 'array',
                'items'        => array(
                    'type' => 'string',
                ),
                'uniqueItems'  => true,
            ),
            'attributes' => array(
                'description' => '巢狀屬性測試',
                'type'        => 'object',
                'properties'  => array(
                    'color' => array( 'type' => 'string' ),
                    'size'  => array( 'type' => 'string', 'enum' => array('S', 'M', 'L') ),
                ),
                'required'    => array('size'),
            ),
        ),
        'required'             => array( 'name', 'price' ),
        'additionalProperties' => false, // 不允許定義以外的垃圾欄位
    );
}

真正的挑戰:如何執行驗證?

這是一個坑。WordPress 的 register_rest_route 雖然讓你定義 schema,但它預設不會自動幫你依照這個 schema 進行嚴格驗證(除非你是使用 REST Controller 模式並繼承 WP_REST_Controller,它會有部分整合)。

如果你只是寫 Closure (匿名函式) 作為 callback,你需要手動觸發驗證。身為工程師,我們當然要自動化這個過程。我們可以使用 rest_validate_request_arg 這個 filter,或者更直接地,在處理請求前先跑一次 Schema Validator。

雖然 WordPress 內建了 rest_validate_value_from_schema 函式,但它對複雜 Schema(如 oneOf, anyOf)的支援度有限。在浪花科技的專案中,如果是複雜的企業級 API,我通常會引入強大的第三方庫,例如 opis/json-schema (支援 Draft 2020-12) 或 justinrainbow/json-schema

使用 WordPress 原生函式進行驗證的實戰

如果不想裝 Composer 套件,我們可以寫一個簡單的中介層(Middleware)或是 Helper Function 來達成基本的 Schema 驗證:

function roamer_validate_request( $request ) {
    $schema = roamer_product_schema();
    $params = $request->get_json_params();

    // 這是 WordPress 內建的驗證器
    $is_valid = rest_validate_value_from_schema( $params, $schema, 'params' );

    if ( is_wp_error( $is_valid ) ) {
        return $is_valid;
    }

    // 額外處理 required (WP 內建函式有時對頂層 required 判斷較寬鬆)
    if ( isset( $schema['required'] ) ) {
        foreach ( $schema['required'] as $field ) {
            if ( ! isset( $params[ $field ] ) ) {
                return new WP_Error( 'rest_missing_callback_param', "缺少必要參數: $field", array( 'status' => 400 ) );
            }
        }
    }

    return true;
}

然後在你的 API Callback 最前面呼叫它:

function roamer_create_product( WP_REST_Request $request ) {
    $validation = roamer_validate_request( $request );
    if ( is_wp_error( $validation ) ) {
        return $validation;
    }

    // 資料是乾淨的,開始寫入資料庫...
    $params = $request->get_json_params();
    // ...
}

進階技巧:巢狀結構與複雜邏輯

JSON Schema 的強大之處在於處理「巢狀結構」。例如上面的 attributes 欄位,我們定義了 size 必須是 ‘S’, ‘M’, ‘L’ 其中之一(Enum)。如果前端傳來 ‘XL’,驗證器會直接擋掉。

這在處理 WooCommerce 訂單結構、或是複雜的 CRM 資料同步時非常有用。你不希望寫這種 Code:

if ( isset($data['attributes']) && isset($data['attributes']['size']) && in_array($data['attributes']['size'], ['S','M','L']) ) ...

這簡直是災難。用 Schema,這一切都變得宣告式(Declarative),一目了然。

Eric 的工程師小囉嗦:不要過度設計

雖然 JSON Schema 很棒,但也要提醒大家:不要為了 Schema 而 Schema。如果你只是一個接收「聯絡我們」表單的簡單 API,只有兩個欄位,或許直接用 WordPress 的 validate_callback 就夠了。引入完整的 Schema 驗證流程會有一定的效能開銷(雖然微乎其微)。

但如果你的系統涉及金流、會員資料同步、或者是 SaaS 應用的核心資料交換,請務必把 JSON Schema 加上去。這能讓你的後端像個堡壘一樣,把所有髒東西都擋在護城河外面。

總結

使用 JSON Schema 來設計與驗證 WordPress REST API,能為你帶來以下優勢:

  • 安全性提升:嚴格過濾輸入資料,防止 Injection 或異常資料導致的錯誤。
  • 文件自動化:Schema 就是活的文件。
  • 開發效率:減少手寫重複的驗證邏輯(Boilerplate code)。
  • 維護性:資料結構一目了然,新進工程師也能快速看懂 API 規範。

把資料驗證做好了,你晚上睡覺都會比較安穩,不用擔心半夜被叫起來修 Bug。

延伸閱讀

你的 API 架構需要健檢嗎?
如果你正在為企業開發複雜的 WordPress 系統,或者遇到資料驗證與 API 串接的瓶頸,歡迎找浪花科技聊聊。我們擅長處理高併發、高安全性的系統架構。
立即聯繫我們

常見問題 (FAQ)

Q1: 為什麼要用 JSON Schema 而不是直接在 PHP 裡面寫 if-else 檢查?

JSON Schema 提供了標準化、宣告式的驗證方式。它比 if-else 更易讀、更易維護,且可以處理深層巢狀結構的驗證,還能直接作為 API 文件使用,大幅降低前後端溝通成本。

Q2: WordPress 內建的驗證功能夠用嗎?

對於簡單的 API,內建的 validate_callbackrest_validate_value_from_schema 通常足夠。但若涉及複雜邏輯(如 oneOf、相依欄位驗證),建議引入專門的 PHP JSON Schema Validator 函式庫。

Q3: 實作 Schema 驗證會影響 API 效能嗎?

會有極些微的影響,因為需要解析 JSON 和比對規則。但在現代伺服器上,這點開銷與其帶來的安全性與資料完整性好處相比,是絕對值得的。比起處理髒資料導致的錯誤修復,驗證的成本微乎其微。

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