سلام
توی مقاله قبل درباره اینکه خود API چیه توضیح دادم. اما ساخت API توی اکثر زبانها بصورت کلی مثل هم هست. مثل همیشه وردپرس هم سعی کرده به شیوه خودش این عمل ساخت API رو ساده کنه.
API های پیشفرض وردپرس
وردپرس برای بخش های مختلف سایت مثل: نوشته ها، برگه ها، تنظیمات و خلاصه هر قسمتی که وردپرس داره، یه API ساخته. تمام API هایی که توی وردپرس ساخته میشن، بصورت پیشفرض از طریق بیس /wp-json/ در دسترس هستن:
اگه این آدرس رو باز کنید، لیست تمام API هایی که روی سایت من فعال هست رو میبینید. اون Route هایی که با /wp/ شروع شدن API هایی اصلی وردپرس هستن. اما وردپرس به جز اینها چند API دیگه هم روی خودش داره:
- /batch/
- /oembed/
- /wp-site-health/
- /wp-block-editor/
/batch/
API های batch یک API بسیار جالب هست که قابلیت اینو داره که وقتی میخواید برای چند Route درخواست بفرستید، بجای اینکه برای هر کدوم جداگانه بفرستید و چندین زمان صرف ارسال و دریافت اطلاعات بشه، میتونید از طریق این API نتیجه(Response) تمام Route هایی که میخواستید یکی یکی درخواست ارسال کنید رو بصورت آرایه دریافت کنید.
/oembed/
API های oembed اجازه نمایش محتوا سایت های دیگه رو به وردپرس میدن. مثل Soundcloud و…
/wp-site-health/
این بخشی برای بررسی سلامت سایت و اطلاعاتی هست که از منوی «سلامت سایت» توی خود داشبورد میتونید ببینید.
/wp-block-editor/
این API ها از طریق ویرایشگر گوتنبرگ(Gutenberg) اضافه شده و برای کار با بلاک های این ادیتور هست.
تغییر آدرس بیس پیشفرض API در وردپرس
همونطور که گفتم همه API های وردپرس از بیس /wp-json/ میان. حالا اگه شما بخواید این رو عوض کنید و مثلا بزارید /api/ باید از فیلتر «rest_url_prefix» استفاده کنید:
<?php
function change_wp_json_prefix_url( $prefix ) {
return 'api';
}
add_filter( 'rest_url_prefix', [$this, 'change_wp_json_prefix_url'] );
برای اینکه در ادامه مقاله به مشکل نخوریم، فرض میکنیم آدرس بیس /wp-json/ هست.
ساخت اولین API
ساخت API توی وردپرس بسیار ساده هست. یکی از خوبی های سیستم ساخت API توی وردپرس اینه که بعضی از ارورها رو خودش مدیریت میکنه و نیازی نیست شما چک کنید. مثلا برای بررسی آرگومان های اجباری و نوع آرگومان ها، شما لیست آرگومان ها و نوعشون رو به Route مربوطه معرفی میکنید، وردپرس بررسی میکنه که آیا تمام موارد اجباری ارسال شده یا نه و مواردی که ارسال شدن هم نوعشون چیه(string, array, integer, …). در صورتی که این شرایط اروری داشته باشه، وردپرس با کد ۵۰۰ متن ارور رو برمیگردونه و اجازه نمیده کد شما اجرا بشه.
همونطور که میدونید همه کارها توی وردپرس از طریق هوک ها(اکشن و فیلترها) انجام میشه. پس برای ساخت route ها هم باید اکشن وجود داشته باشه. اسم اکشنی که این کار رو برامون میکنه «rest_api_init» هست. توی این اکشن، تابعی که برای ساخت Route ها استفاده میشه «register_rest_route» هست.
برای اینکه بهتر بتونید متوجه بشید که چی به چیه فرض کنید میخوایم یه API بسازیم که پیامک ارسال کنه.
مثال واقعی برای API
اولین پارامتر تابع، Namespace هست. برای مرتب سازی API هایی که توی وردپرس وجود دارن، هر Route باید توی یک Namespace قرار بگیره. این بخش از Route دقیقا بعد از بیس قرار میگیره. معمولا مقدار namespace ترکیبی از اسم پروژه و نسخه API هست. برای مثال اگه مقدار namespace رو بزارید «custom/v1»، آدرس بیس API های شما به این صورت میشه:
/wp-json/custom/v1/
پارامتر دوم هم آدرس Route هست. که هر چیزی که در نظر دارید میزارید و این مقدار در ادامه namespace میاد. مثلا اگه «sms» باشه:
/wp-json/custom/v1/sms
و اما پارامتر سوم که مهمترین پارامتر هست. این پارامتر برای انجام تنظیمات این Route هست. تنظیمات بصورت آرایه به Route وصل میشه و شامل سه بخش میشه.
- methods: باید لیست متدهای HTTP که این Route قرار پشتیبانی کنه وارد کنید.
- args: لیست آرگومان ها به همراه نوع هر کدوم و در صورت نیاز توضیح و…
- callback: اسم فانکشنی که این Route باید اجرا کنه.
پیشنهاد میشه برای methods بجای اینکه خودتون دستی وارد کنید، از کلاس WP_REST_Server کمک بگیرید، توی این کلاس لیست تمام متدها واضح تر نوشته شده و کارتون رو راحت تر میکنه.
<?php
$namespace = "custom/v1";
register_rest_route( $namespace, "/sms", [
'methods' => WP_REST_Server::READABLE,
'args' => [
'limit' => [
'type' => 'integer',
'default' => 20,
'required' => false,
],
'offset' => [
'type' => 'integer',
'default' => 0,
'required' => false,
]
]
'callback' => 'get_phone_numbers',
] );
function get_phone_numbers( $request ) {
}
حالا میتوانیم با استفاده از GET برای آدرس /wp-json/custom/v1/sms درخواست ارسال کنیم. برای این Route دو آرگومان تعریف شده که limit و offset اسم دارن. هیچکدوم هم اجباری نیستند(برای آرگومان هایی که اجباری میشه required رو ننوشت، یعنی پارامتر بصورت پیشفرض اختیاری هست). همچنین limit بصورت پیشفرض ۲۰ هست و offset هم بصورت پیشفرض ۰. یعنی حداکثر ۲۰ شماره موبایل رو بر میگردونه اما اگه مقدارش رو عوض کنن هر چقدر که نوشته شده بر میگردنه. همیشه سعی کنید تعداد نتایج برگشتی رو محدود کنید
با اینکه فعلا هیچ پردازشی انجام نمیشه و چیزی بر نمیگردونه اما حداقل ارور ۴۰۴ نمیده! :). اما میتونید تست کنید و ببینید که با متد POST ارور ۴۰۴ خواهد داد. چون متد این Route رو Readable قرار دادیم و Readable فقط شامل GET میشه.
<?php
function get_phone_numbers( $request ) {
$params = $request->get_params();
$limit = $params['limit'];
$offset = $params['offset'];
$users = get_users( [
'number' => $limit,
'offset' => $offset,
] );
$phone_numbers = [];
foreach( $users as $user ) {
$phone_numbers[] = get_user_meta( $user->ID, 'phone_number', true );
}
$response = \WP_REST_Controller::prepare_response_for_collection( $phone_numbers );
return new \WP_REST_Response( $response, 200 );
}
فانکشن get_params کارش گرفتن پارامترهایی(آرگومانهایی) که ارسال شدن هست.
اون وسط که همه چیز مشخصه و توابع عمومی وردپرس هست اما دو خط آخر:
یک کلاس توی ودرپرس وجود داره به نام WP_REST_Controller کارش مدیریت Routeها و کلاس اصلی REST API وردپرس هست. اما یکی از متدهایی که داره prepare_response_for_collection هست و قبل از ارسال نتیجه(Response) استفاده میشه که مطمئن بشه اطلاعات درست ارسال شده.
در پایان هم از کلاس WP_REST_Response استفاده کردیم که کارش ارسال نتیجه(Response) هست. اولین ورودی نتیجهای هست که میخواید ارسال بشه. دومین ورودی، کد HTTP هست که همراه این نتیجه ارسال بشه. که اینجا نتیجه ای که بر میگردونیم یه آرایه از شماره موبایلها بصورت JSON خواهد بود. حتی اگه خواستید ارور ارسال کنید هم باید از WP_REST_Response استفاده کنید و ورودی اول رو میتونید به هر صورتی که میخواید قرار بدید، مثلا مستقیما کلاس WP_Error رو بزارید یا مثلا فقط یه استرینگ(String) رو برگردونید اما دقت کنید که کد HTTP رو باید متناسب وارد کنید(یعنی از کدهای ۴xx یا ۵xx استفاده کنید)
بهنام
۱۶ اردیبهشت ۱۴۰۲ @ ۱:۱۳ ب٫ظ
شاید باورت نشه ولی اینجام نظر میذارم :))
(تایم استراحت برنامه نویس خسته)