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 設計宣言:打造溝通無礙、可擴展的數位橋樑
- API 回傳一坨垃圾?資深工程師教你用 JSON Schema 打造 WordPress 滴水不漏的數據防火牆
- 你的 WordPress 正在大開後門嗎?資深工程師的 Webhook 設計與安全驗證終極指南
你的 API 架構需要健檢嗎?
如果你正在為企業開發複雜的 WordPress 系統,或者遇到資料驗證與 API 串接的瓶頸,歡迎找浪花科技聊聊。我們擅長處理高併發、高安全性的系統架構。
立即聯繫我們
常見問題 (FAQ)
Q1: 為什麼要用 JSON Schema 而不是直接在 PHP 裡面寫 if-else 檢查?
JSON Schema 提供了標準化、宣告式的驗證方式。它比 if-else 更易讀、更易維護,且可以處理深層巢狀結構的驗證,還能直接作為 API 文件使用,大幅降低前後端溝通成本。
Q2: WordPress 內建的驗證功能夠用嗎?
對於簡單的 API,內建的 validate_callback 或 rest_validate_value_from_schema 通常足夠。但若涉及複雜邏輯(如 oneOf、相依欄位驗證),建議引入專門的 PHP JSON Schema Validator 函式庫。
Q3: 實作 Schema 驗證會影響 API 效能嗎?
會有極些微的影響,因為需要解析 JSON 和比對規則。但在現代伺服器上,這點開銷與其帶來的安全性與資料完整性好處相比,是絕對值得的。比起處理髒資料導致的錯誤修復,驗證的成本微乎其微。






