طراحی رابط های برنامه نویسی برنامه (API) می تواند یک تلاش چالش برانگیز باشد. API های خوب دارای رابط های ساده ای هستند که استفاده از آنها آسان تر و ساده تر است. در پشت این رابط کاربری ساده می توان بسیاری از فعل و انفعالات سیستم های پیچیده را مشاهده کرد. این تعاملات می توانند در یک کار نهایی که به طور واضح تایید و مشخص شده است، اختلال ایجاد کنند. با گذشت زمان، ممکن است از توسعه دهندگان خواسته شود تا منطق تجاری اضافی خود را برای نقاط پایانی (ENDPoints) موجود، مورد استفاده نیز قرار دهند. بنابراین یک تماس API واحد (Single API Call)، با بیش از 12 سیستم به عنوان بخشی از جریان اصلی خود نیز تعامل دارد.
حال به نظرتان خوب نیست که بتوان یک Pipeline یا خط لوله ای ایجاد کنیم که سر راست باشد، اما دارای قابلیت اضافه کردن کارهای اضافی باشد؟
منظور از Hooks / Actions چیست ؟
Hook (معروف به action / filter) اسمی است که توسط جامعه وردپرس، به رویداد ها و تماس های مربوط به آنها نیز داده می شود. اگر در حال حاضر تجربه برنامه نویسی دارید، ممکن است با callback ها و الگوهای publisher-subscriber نیز آشنا باشید. در هنگام پردازش، ممکن است سیستم یک رویداد را آغاز کند که عدد صفر را برای بسیاری از عملکرد های مشترک آن رویداد، فراخوانی کند. به عنوان مثال در پاسخ به بارگیری صفحه، وردپرس با استفاده از توابع، برای بارگذاری هدر، عنوان، لیست کردن پست ها یا جستجوی قالب مناسب نیز فرا خوانی میشود. این وظایف بدون ایجاد اختلال در فرایند اصلی تولید صفحه، اجرا می شوند.
ایده hook ها چیز جدیدی نیست!
در واقع Hook ها توسط وردپرس ابداع نشده اند. وردپرس فقط در چرخه پردازش صفحات سمت سرور، hook ها را به درستی پیاده سازی می کند. یکی از بزرگترین ویژگی هایی که یک پلتفرم می تواند داشته باشد، استفاده از Hook هاست. با استفاده از این Hook ها، شرایطی برای کاربران جور میشود که بتوانند عملکردهای خود را که شامل افزونه ها یا موضوعاتی است که به وردپرس متصل هستند، بنویسند. سپس هر زمان که نیاز بود، کد مورد نظر خود را اجرا کنند.
برای مثال زمانی که قصد تغییر هدر ارسال شده به کاربر را دارید، مشکلی نیست. با متصل شدن به رویداد wp-headers، می توانید هدر ها به دلخواه خود نیز تغییر دهید.
چرا Hook یک API محسوب می شود؟
Hook ها، در زمینه های زیادی موثر و مفید هستند:
- راه اندازی برخی از امور جانبی
- فراخوانی یک سیستم دیگر از طریق دستور PHP cURL
- ساخت یک object یا شی و قرار دادن آن در صف وظایفی که بعدا قرار است توسط سیستم دیگری دریافت شود.
- ارسال ایمیل و …
همه اینها را می توان بدون نیاز به کدر کردن جریان اصلی یک نقطه پایان مشخص که ممکن است در این فرایند نسخه جدید API باشد، انجام داد.
اگر نقطه پایان برای ایجاد یک کاربر است، می توانیم بر ایجاد پرونده کاربر در پایگاه داده تمرکز کنیم و در طول راه فقط با کسانی که در این پروسه گوش می دهند، تماس بگیرید.
ایجاد مکانیسم های اساسی
برای شروع، باید بتوانیم یک hook یا action اضافه کنیم. ما همچنین به توانایی برداشتن Hook و در نهایت راه اندازی Hook نیاز داریم. هنگامی که ما این مکانیسم را تعریف میکنیم، فقط باید مطمئن شویم که آنها در API گنجانده شده اند. سپس مکان هایی را در API خود پیدا کنیم که ممکن است بخواهیم این Hook ها را فراخوانی کنیم.
مثال زیر، یکی از راه های است که ممکن است بخواهیم تنظیمات زیر را انجام دهیم.
تنظیم hooks.php :
// Global array which will hold all of our hooks
// We will reference this array in each function to add/remove/call our hooks
// The code below should also be seen by any callbacks we write for the system later.
$hooks = [];
// Below are global functions that can be seen from our API code
// The add_hook method will allow us to attach a function (callback) to a given event name
function add_hook($event_name, $callback) {
global $hooks;
if ($callback !== null) {
if ($callback) {
// We can set up multiple callbacks under a single event name
$hooks[$event_name][] = $callback;
}
}
}
// Super easy to implement, we remove the given hook by its name
function remove_hook($event_name) {
global $hooks;
unset($hooks[$event_name]);
}
// When we want to trigger our callbacks, we can call this function
// with its name and any parameters we want to pass.
function do_hook($event_name, …$params) {
global $hooks;
if (isset($hooks[$event_name])) {
// Loop through all the callbacks on this event name and call them (if defined that is)
// As we call each callback, we given it our parameters.
foreach ($hooks[$event_name] as $function) {
if (function_exists($function)) {
call_user_func($function, …$params);
}
}
}
}
اکنون که فایل hooks.php خود را با استفاده از دستورات بالا ایجاد کرده ایم، فقط کافیست آن را در API خود قرار دهیم تا این توابع دیده شوند. پس از آن، فقط باید Hook ها را در API قرار دهید. در این مثال ما با استفاده از do-hook این کار را انجام داده ایم.
به عنوان یک مثال ساده، فرض کنید ما یک API برای ثبت نام کاربری جدید در سیستم خود در اختیار داریم. ممکن است یک نقطه پایانی REST API به نام addUser/ نیز داشته باشیم. در ساده ترین حالت، فرض کنید که در اینجا هدف این است که به طور تقریبا مستقیم نام و سن کاربر جدید را به سادگی در جدول کاربران دیتابیس، وارد کنید:
مثال:
// POST endpoint for adding a user (part of a larger API class)
public function addUser($name, $age) {
if ($this->request->method === ‘post’) {
try {
$this->db->insert(‘users’, [‘name’ => $name, ‘age’ => $age]);
return new Response(200, ‘User created successfully!’);
} catch (Exception $e) {
// Oops, something went wrong.
// Do some logging or whatever.
}
}
// If not a POST request, return http status 400
return new Response(400, ‘Bad request’);
}
کد بالا یک دیدگاه بسیار ساده و کلی در مورد چگونگی اضافه کردن یک کاربر جدید به دیتابیس است. ایده اصلی این است که اگر کسی به نقطه پایانی API /addUser ما تماس بگیرد، در نهایت به این تابع می رسد که در آن نام و سن کاربر از داده های ارسال شده، خارج می شود. ابتدا بررسی میکنیم که آیا آنها طبق قوانین استاندارد REST پست منتشر می کنند و سپس سعی میکنیم کاربر را در جدول users نیز قرار دهیم.
در مرحله بعد، اگر کاربر با موفقیت وارد شود، یک hook را فراخوانی می کنیم تا به هر کدی که کاربر ایجاد کرده است، گوش دهد.
برترین تکنیک های hook :
- Hook های خود را لاغر و متوسط نگه دارید.
- هر callback را به صورت جداگانه و ساده دیباگ کنید.
- به عملکرد مورد نیاز فکر کنید و از hook سو استفاده نکنید.
- با جامعه dev در ارتباط باشید.