چرا پاسخ REST API شما ناقص است؟ راهنمای تخصصی register_rest_field
تابع register_rest_field برای افزودن فیلد سفارشی به پاسخ REST API وردپرس؛ بررسی پارامترها، get_callback، update_callback و اشتباهات رایج.
چرا فیلد سفارشی در REST API یک نیاز جدی است؟
وردپرس بهصورت پیشفرض فیلدهای پایه هر منبع را در REST API ارائه میدهد: عنوان، محتوا، نویسنده، تاریخ و موارد مشابه. اما افزونهها معمولاً دادههای سفارشی نیز دارند: قیمت محصول، شماره تلفن، وضعیت ویژه، امتیاز و غیره. اگر این دادهها در REST API نمایش داده نشوند، اپلیکیشنهای موبایل و فرانتاندهای Headless نمیتوانند به آنها دسترسی داشته باشند. تابعregister_rest_field ابزار اصلی برای حل این مسئله است.
تابع register_rest_field چیست؟
تابعregister_rest_field() یک تابع هسته وردپرس است که در فایل wp-includes/rest-api.php تعریف شده است. این تابع یک فیلد سفارشی به پاسخ REST API اضافه میکند.
این تابع باید در هوک rest_api_init فراخوانی شود. اگر در هوک دیگری فراخوانی شود، فیلد بهدرستی ثبت نمیشود.
نکته مهم: این تابع برای افزودن فیلد به پاسخ موجود استفاده میشود، نه برای ساخت endpoint جدید. برای ساخت endpoint، از register_rest_route استفاده کنید که در راهنمای register_rest_route آمده است.
امضای تابع و پارامترها
امضای این تابع بهشکل زیر است:function register_rest_field( $object_type, $attribute, $args = array() ) {
// ...
}
پارامتر اول (object_type) نوع منبع است: post، user، term، comment یا نامک پست تایپ سفارشی.
پارامتر دوم (attribute) نام فیلد سفارشی است.
پارامتر سوم (args) آرایهای از تنظیمات است.
مهمترین پارامترهای این آرایه عبارتاند از:
- get_callback: تابعی که مقدار فیلد را در پاسخ برمیگرداند
- update_callback: تابعی که مقدار فیلد را از درخواست ذخیره میکند
- schema: تعریف ساختار فیلد برای مستندسازی و اعتبارسنجی
- permission_callback: تابع بررسی دسترسی برای ویرایش
هوک rest_api_init و زمان ثبت
این تابع باید در هوکrest_api_init فراخوانی شود:
add_action( 'rest_api_init', 'myplugin_register_rest_fields' );
function myplugin_register_rest_fields() {
register_rest_field( 'post', 'myplugin_featured', array(
'get_callback' => 'myplugin_get_featured_field',
'update_callback' => 'myplugin_update_featured_field',
'schema' => array(
'description' => 'آیا این نوشته ویژه است',
'type' => 'boolean',
'context' => array( 'view', 'edit' ),
),
) );
}
نکته مهم: پارامتر context در schema تعیین میکند که فیلد در چه زمینهای نمایش داده شود.
get_callback و update_callback
**get_callback** مقدار فیلد را برمیگرداند. این تابع سه پارامتر دریافت میکند:$object، $field_name، $request.
نمونه:
function myplugin_get_featured_field( $object, $field_name, $request ) {
$post_id = absint( $object['id'] );
$value = get_post_meta( $post_id, '_myplugin_featured', true );
return (bool) $value;
}
**update_callback** مقدار فیلد را ذخیره میکند. این تابع چهار پارامتر دریافت میکند: $value، $object، $field_name، $request.
نمونه:
function myplugin_update_featured_field( $value, $object, $field_name, $request ) {
$post_id = absint( $object['id'] );
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return new WP_Error( 'rest_cannot_edit', 'دسترسی غیرمجاز', array( 'status' => 403 ) );
}
update_post_meta( $post_id, '_myplugin_featured', (bool) $value );
return true;
}
نکته مهم: در update_callback باید بررسی capability انجام شود چرا که امکان تغییر داده وجود دارد. راهنمای current_user_can در صفحه current_user_can آمده است.
schema و مستندسازی فیلد
پارامترschema ساختار فیلد را تعریف میکند و امکان مستندسازی خودکار و اعتبارسنجی را فراهم میسازد:
'schema' => array(
'description' => 'قیمت محصول به تومان',
'type' => 'integer',
'minimum' => 0,
'context' => array( 'view', 'edit' ),
'arg_options' => array(
'sanitize_callback' => 'absint',
),
),
نکته مهم: با تعریف schema دقیق، میتوانید از ابزارهای مستندسازی OpenAPI استفاده کنید و اعتبارسنجی خودکار داشته باشید.
permission_callback برای ویرایش
پارامترpermission_callback تعیین میکند که آیا کاربر مجاز به ویرایش این فیلد است:
'permission_callback' => function() {
return current_user_can( 'edit_posts' );
},
اگر این پارامتر تعریف نشود، وردپرس از permission_callback خود endpoint استفاده میکند. با این حال، برای فیلدهای حساس، تعریف صریح توصیه میشود.
کاربردهای عملی در افزونه
افزودن فیلد «قیمت» به پست تایپ محصول:add_action( 'rest_api_init', 'myplugin_register_product_fields' );
function myplugin_register_product_fields() {
register_rest_field( 'product', 'price', array(
'get_callback' => function( $object ) {
return (int) get_post_meta( $object['id'], '_myplugin_price', true );
},
'update_callback' => function( $value, $object ) {
if ( ! current_user_can( 'edit_post', $object['id'] ) ) {
return new WP_Error( 'rest_cannot_edit', 'دسترسی غیرمجاز', array( 'status' => 403 ) );
}
update_post_meta( $object['id'], '_myplugin_price', absint( $value ) );
return true;
},
'schema' => array(
'description' => 'قیمت محصول به تومان',
'type' => 'integer',
'minimum' => 0,
'context' => array( 'view', 'edit' ),
),
) );
}
افزودن فیلد «شماره تلفن» به کاربران:
register_rest_field( 'user', 'myplugin_phone', array(
'get_callback' => function( $user ) {
$current_user_id = get_current_user_id();
if ( $current_user_id !== (int) $user['id'] && ! current_user_can( 'list_users' ) ) {
return null;
}
return get_user_meta( $user['id'], 'myplugin_phone', true );
},
'update_callback' => function( $value, $user ) {
$current_user_id = get_current_user_id();
if ( $current_user_id !== (int) $user['id'] && ! current_user_can( 'edit_users' ) ) {
return new WP_Error( 'rest_cannot_edit', 'دسترسی غیرمجاز', array( 'status' => 403 ) );
}
update_user_meta( $user['id'], 'myplugin_phone', sanitize_text_field( $value ) );
return true;
},
'schema' => array(
'description' => 'شماره تلفن کاربر',
'type' => 'string',
'context' => array( 'view', 'edit' ),
),
) );
راهنمای توابع استفادهشده: get_post_meta، update_post_meta، current_user_can.
نکات امنیتی و اشتباهات رایج
اشتباه اول، نبودget_callback است. بدون این تابع، فیلد در پاسخ نمایش داده نمیشود.
اشتباه دوم، نبود update_callback است. بدون این تابع، فیلد از طریق REST API قابل ویرایش نیست.
اشتباه سوم، نبود بررسی capability در update_callback است. این خطا میتواند به تغییر داده توسط کاربران غیرمجاز منجر شود.
اشتباه چهارم، نبود sanitize در update_callback است. داده کاربر باید پاکسازی شود.
اشتباه پنجم، افشای داده حساس در get_callback است. اگر فیلد حساس باشد، باید بر پایه capability بررسی شود.
اشتباه ششم، نبود schema است. بدون schema، فیلد در مستندات API نمایش داده نمیشود.
اشتباه هفتم، ثبت برای object_type نامعتبر است. باید از نامک معتبر استفاده کنید.
اشتباه هشتم، نبود تست است. باید در سناریوهای کاربر مهمان، کاربر واردشده، کاربر غیرمجاز و داده نامعتبر تست کنید.
تحلیل فنی پیشرفته
در نگاه مهندسی، تابعregister_rest_field() یک نقطه معماری در لایه REST API Representation است که بر چند لایه سیستم اثر میگذارد. لایه اول لایه Serialization است. این تابع امکان افزودن فیلد به پاسخ JSON را فراهم میکند.
لایه دوم لایه Deserialization است. با تعریف update_callback، امکان ذخیره مقدار ارسالی از کلاینت فراهم میشود.
لایه سوم لایه Schema Validation است. با تعریف schema، وردپرس اعتبارسنجی خودکار انجام میدهد.
لایه چهارم لایه Permission است. permission_callback بهعنوان محافظ امنیتی عمل میکند.
لایه پنجم لایه Caching است. پاسخهای REST API معمولاً کش نمیشوند اما در صورت کش، فیلدهای سفارشی نیز کش میشوند.
لایه ششم لایه Multisite است. در شبکههای Multisite، فیلدها در هر سایت مستقل کار میکنند.
لایه هفتم لایه Testing است. تستهای End-to-End باید همه سناریوها را پوشش دهند.
مفاهیم پایهای API Design در API design در ویکیپدیا توضیح داده شده است.
برای مطالعه بیشتر روی توابع مرتبط، میتوانید به راهنمای register_rest_route، راهنمای current_user_can، راهنمای is_user_logged_in، راهنمای get_post_meta، راهنمای update_post_meta، راهنمای register_post_type و راهنمای esc_html مراجعه کنید.
پرسشهای پرتکرار
تفاوتregister_rest_field و register_rest_route چیست؟ اولی فیلد به پاسخ موجود اضافه میکند و دومی endpoint جدید میسازد.
آیا میتوان فیلد را فقط برای یک پست تایپ خاص ثبت کرد؟ بله، با پاس دادن نامک آن پست تایپ.
آیا فیلد در ویرایشگر بلوک نمایش داده میشود؟ تنها اگر با register_meta و show_in_rest => true همراه باشد.
چطور فیلد را قابل ویرایش کنیم؟ با تعریف update_callback.
آیا فیلد از احراز هویت استفاده میکند؟ بله، از همان روشهای احراز هویت REST API.
ادامه مسیر
تابعregister_rest_field() ابزار اصلی وردپرس برای افزودن فیلد سفارشی به پاسخ REST API است. استفاده درست از آن یعنی تعریف get_callback و update_callback، تعریف schema دقیق، بررسی capability در ویرایش و تست در سناریوهای مختلف. اشتباههای کوچک در این تابع اغلب به پاسخ ناقص یا افشای داده منجر میشوند.
اگر این تابع را در پروژهای واقعی به کار بردهاید و رفتار غیرمنتظرهای دیدهاید — بهخصوص در اتصال اپلیکیشن موبایل یا در سناریوهای Headless — تجربهتان میتواند راهگشای دیگران باشد. کدام بخش بیشترین زمان را از شما گرفت؟ دیدگاه خود را بنویسید.