طراحی رابط های برنامه نویسی برنامه (API) می تواند یک تلاش چالش برانگیز باشد. API های خوب دارای رابط های ساده ای هستند که استفاده از آنها ساده و آسان است. در پشت این رابط کاربری ساده می توان بسیاری از فعل و انفعالات پیچیده سیستم را مشاهده کرد و این تعاملات واقعاً می تواند آب یک وظیفه نهایی را به طور واضح مشخص کند. با گذشت زمان ، ممکن است از توسعه دهندگان خواسته شود تا منطق تجاری اضافی را برای نقاط پایانی موجود “مورد استفاده قرار دهند”. سپس قبل از اینکه بدانید ، یک تماس API واحد با بیش از دوازده سیستم به عنوان بخشی از جریان اصلی خود تعامل دارد.

آیا خوب نیست اگر بتوانیم خط لوله ای را توسعه دهیم که مستقیم است اما با قابلیت افزودن کارهای اضافی بعداً بدون پوشاندن جریان اصلی؟ این مقاله به شما نشان می دهد که چگونه می توانید ایده ای را از وردپرس و به طور کلی برنامه نویسی اقتباس کنید تا به API های خود توانایی انجام تعاملات قوی تر را بدهید.

قلاب/اقدامات چیست؟

آ قلاب (با نام مستعار اقدامات/فیلترها) نامی است که جامعه وردپرس به رویدادها و تماس های مربوط به آنها می دهد. اگر تجربه ای در برنامه نویسی دارید ، ممکن است با فراخوانی و برنامه های تماس آشنا باشید الگوی ناشر – مشترکبه در طول پردازش ، یک سیستم ممکن است رویدادی را آغاز کند که صفر را برای بسیاری از توابع مشترک آن رویداد صفر می کند. به عنوان مثال ، در پاسخ به بارگیری صفحه ، وردپرس با توابع برای بارگذاری سرصفحه ، بارگذاری عنوان ، لیست پست ها یا جستجوی قالب مناسب تماس می گیرد. این وظایف بدون به هم ریختن فرایند اصلی تولید صفحه اجرا می شوند.

ایده پشت قلاب چیز جدیدی نیست و توسط وردپرس ابداع نشده است. با این حال ، وردپرس در چرخه عمر پردازش صفحات سمت سرور آنها را به خوبی پیاده سازی کرد. به نظر من ، این استفاده از قلاب ها احتمالاً بزرگترین ویژگی پلتفرم است. با استفاده از این قلاب ها ، کاربران می توانند عملکردهای خود را – اعم از افزونه ها یا موضوعات – که به وردپرس متصل می شوند ، بنویسند و هر زمان که نیاز بود ، هر کد را که می خواهید اجرا کنند. آیا نیاز به تغییر سرصفحه ارسال شده به کاربر دارید؟ مشکلی نیست: به آن متصل شوید wp_headers رویداد و می توانید هدرها را به دلخواه تغییر دهید.

چرا از Hooks در API استفاده می کنیم؟

قلاب ها برای بسیاری از موارد مفید هستند ، از جمله ایجاد برخی از کارهای جانبی ، فراخوانی یک سیستم دیگر از طریق دستور PHP cURL ، ساختن یک شی و قرار دادن آن در صف وظیفه که بعداً توسط یک سیستم دیگر دریافت شود ، ارسال ایمیل و موارد دیگر. همه اینها را می توان بدون نیاز به کدر کردن جریان اصلی یک نقطه پایانی مشخص (و احتمالاً مجبور کردن نسخه API جدید در این فرایند) انجام داد.

اگر نقطه پایانی برای ایجاد یک کاربر است ، می توانیم بر ایجاد پرونده کاربر در پایگاه داده تمرکز کنیم و در طول راه فقط با کسانی که در این فرایند گوش می دهند تماس بگیرید. شاید پس از ایجاد پرونده کاربر ، ما رویدادی را ارسال کنیم که می گوید “هر کسی که به این موضوع گوش می دهد ، من فقط یک کاربر ایجاد کرده ام و اطلاعات او در اینجا آمده است”. شاید برخی از عملکردهای تماس در رویداد مشترک شده اند و در حال گوش دادن هستند یا شاید هیچکدام اینگونه نیستند. این رویداد واقعاً اهمیتی ندارد.

با استفاده از این سیستم ، می توانیم API های خود را برای کد فراخوانی کنیم که ممکن است بعداً نوشته شود. ما می توانیم این کار را بدون نیاز به لمس خود کد پایانی API انجام دهیم. برای نشان دادن نحوه عملکرد ، بیایید دنده ها را تغییر دهیم و مکانیسم اصلی نحوه شروع این کار را در یک API PHP نشان دهیم. به خاطر داشته باشید که در حالی که از PHP در اینجا استفاده می کنیم ، در واقع می توانیم منطق مشابهی را در برنامه های وب با استفاده از زبان های دیگر پیاده سازی کنیم.

ساخت سازوکارهای اساسی

برای شروع ، ما باید بتوانیم یک قلاب/عمل (که از این پس به آن “قلاب” می گویم) اضافه کنیم. ما همچنین به توانایی حذف قلاب و در نهایت راه اندازی قلاب نیاز داریم. هنگامی که ما این مکانیسم ها را تعریف کردیم ، فقط باید مطمئن شویم که آنها در API گنجانده شده اند و سپس مکان هایی را در API خود پیدا کنیم که ممکن است بخواهیم این قلاب ها را صدا کنیم. در زیر یکی از راه هایی است که ممکن است بخواهیم این را تنظیم کنیم.

اینجاست hooks.php:




$hooks = [];



function add_hook($event_name, $callback) {
    global $hooks;

    if ($callback !== null) {
        if ($callback) {
          
            $hooks[$event_name][] = $callback;
        }
    }
}


function remove_hook($event_name) {
    global $hooks;

    unset($hooks[$event_name]);
}



function do_hook($event_name, ...$params) {
    global $hooks;

    if (isset($hooks[$event_name])) {
      
      
        foreach ($hooks[$event_name] as $function) {
            if (function_exists($function)) {
                call_user_func($function, ...$params);
            }
        }
    }
}

حالا که خودمان را داریم hooks.php فایل ایجاد شده ، ما فقط باید آن را در API خود قرار دهیم تا این توابع دیده شوند. پس از انجام این کار ، فقط باید قلاب ها را با استفاده از API ما وارد کنید do_hookبه

به عنوان یک مثال ساده ، فرض کنید ما یک API برای ثبت نام کاربر جدید در سیستم خود داریم. ممکن است یک نقطه پایانی REST API داشته باشیم به نام /addUserبه به نام سادگی ، فرض کنید که هدف در اینجا این است که به سادگی نام و سن کاربر جدید را در پایگاه داده خود وارد کنید users جدول. تقریباً مستقیم ، درست است؟


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) {
      
      
    }
  }

  
  return new Response(400, 'Bad request');
}

کد بالا یک دیدگاه بیش از حد ساده و کلی در مورد چگونگی اضافه کردن یک کاربر جدید است. ایده این است که اگر کسی بخواهد با API های ما تماس بگیرد /addUser نقطه پایانی ، آنها در نهایت به این تابع می رسند که در آن نام و سن کاربر از داده های ارسال شده خارج می شود. ابتدا بررسی می کنیم که آیا آنها پست می کنند (طبق قوانین REST مناسب) و سپس سعی می کنیم کاربر را در آن وارد کنیم users جدول.

در مرحله بعد ، اگر کاربر با موفقیت وارد شده است ، می خواهیم یک قلاب را صدا بزنیم تا به کدی که کاربر ایجاد کرده است گوش دهد (این شبیه به افزایش یک رویداد در زبان های دیگر است).

وقتی شرایط تغییر کرد چه باید کرد

چند ماه بعد ، ما در بخش بازاریابی خود اصرار داریم که هنگام ایجاد کاربر جدید ، ایمیلی باید با مشخصات کاربر ارسال شود. ممکن است تمایل داشته باشیم یک تابع کمکی را در API بنویسیم ، سپس آن را از طریق این کد پایانی فراخوانی کنیم. عالی است … اگر این تنها چیزی بود که درخواست می شد. اما اگر تیم پشتیبانی بعداً به شما مراجعه کند و از شما بخواهد کاربر را نیز به سیستم Zendesk خود اضافه کنید ، چطور؟ بنابراین شما یک تابع دیگر می نویسید و آن تماس را به این نقطه پایانی نیز متصل می کنید.

نکته بعدی که می دانید ، این نقطه نهایی نه تنها افزودن یک کاربر به پایگاه داده وب سایت ماست ، بلکه برقراری تماس با توابع برای ارسال ایمیل ، اضافه کردن کاربران به Zendesk ، Jira و Microsoft Microsoft و سپس رسیدگی به نتایج موفقیت/شکست آنها است. همه این موارد اضافی واقعاً از نقطه روشن افزودن کاربر به پایگاه داده ما دور می شود. ما می خواهیم با یک رویداد تماس بگیریم و از کد دیگر فقط برای زمانی که کاربر ایجاد می شود و کارهای خود را انجام می دهد ، گوش دهیم – بدون این که ما نیازی به تغییر این نقطه نهایی داشته باشیم. شاید هیچ سرویس دیگری به افزودن کاربر جدید اهمیت ندهد ، بنابراین هیچ کس از هیچ کاری دعوت نمی شود. نقطه پایانی نیازی به اهمیت ندارد. بسیار عالی ، درست است؟

بیایید مثال خود را با نامگذاری قلاب خود ادامه دهیم. این نامی است که همه کد تماس برای گوش دادن به آن نیاز دارد. باز هم ، زبانهای دیگر از این تنظیم به عنوان “رویداد” یاد می کنند ، بنابراین برای یادگیری بیشتر حتماً آن را در زبان مورد نظر خود جستجو کنید.

ما قلاب خود را صدا می زنیم added_userبه ساده و سر اصل مطلب ، فکر نمی کنید؟ هنگامی که نامی داریم ، می توانیم تصمیم بگیریم که کجا می خواهیم این قلاب را صدا کنیم. من فکر می کنم بلافاصله پس از یک درج موفق ایده خوبی خواهد بود:

public function addUser($name, $age) {
  if ($this->request->method === 'post') {
    try {
      $this->db->insert('users', ['name' => $name,  'age' => $age]);
      
      do_hook('added_user', $name, $age);
      return new Response(200, 'User created successfully!');
    } catch (Exception $e) {
      
      
    }
  }

  return new Response(400, 'Bad request');
}

در حال حاضر ما می توانیم ده ها تابع callback در حال گوش دادن به برنامه داشته باشیم added_user قلاب یا به هیچ وجه شاید ما یک تماس تلفنی داشته باشیم که مسئول درج کاربر در Zendesk است و دیگری که نام و سن را تعیین می کند و برای بازاریابی ایمیل ایجاد می کند. این کد “مشترک” می تواند در جایی دیگر در پایگاه کد زندگی کند ، تا زمانی که بتواند کد را مشاهده کند hooks.php کد داخل پروژه API من معمولاً عملکرد callback خود را در یک فایل جداگانه قرار می دهم و آن فایل را در API نیز قرار می دهم. در زیر یک نمونه از تماس تلفنی است که اکنون می تواند از این قلاب جدید ایجاد شده استفاده کند:

function sendContactToMarketing($name, $age) {
  
}

add_hook('added_user', 'sendContactToMarketing');

این قلاب ها را کجا می توانیم قرار دهیم؟

در کد بالا ، ما استفاده از یک قلاب را در یک نقطه انتهایی نشان می دهیم. این قلاب فقط زمانی فعال می شود که /addUser endpoint فراخوانی می شود و تنها پس از موفقیت درج. اما این تنها مکانی نیست که می توانید از این قلاب ها استفاده کنید. شاید در کلاس API خود کد مسیریابی دارید که از طریق بررسی اینکه آیا کلید API معتبر است یا حتی نوع خاصی از درخواست را دریافت کرده اید ، بررسی می شود.

می توانید یک قلاب را در سطح جهانی در API قرار دهید تا هر درخواستی آن را فعال کند. سپس ، بعداً ، کسی می تواند یک چوب نگار بنویسد ، آن را به api_init قلابی را که ایجاد کرده اید و ناگهان شروع به ثبت همه درخواست های انجام شده به API کنید – دوباره ، دست نزنید به کد کلاس API اصلی. همین قلاب ممکن است یک تماس تلفنی دیگر نیز داشته باشد که در صورت سوء استفاده از API بررسی شده و در صورت مشاهده فردی که API شما را با درخواست ها مورد انتقاد قرار می دهد ، آن را به بخش فناوری اطلاعات شما گزارش می دهد.

تصویر زیر نمایی از ظاهر معماری این همه است.

نمودار Hooks In API

از آنجایی که می توانید از این مکانیزم در چندین مکان استفاده کنید ، حتی می توانید قلاب هایی داشته باشید که در ابتدا ، میانه و انتهای نقطه پایانی API نامیده می شوند. همچنین می توانید در نقاط مختلف کل چرخه حیات API در رسیدگی به درخواست قلاب داشته باشید. این واقعاً به طراحی شما بستگی دارد که این موارد را در کجا قرار دهید do_hook تماس می گیرد

بهترین شیوه ها

بیایید اکنون برخی از بهترین شیوه ها را برای شما و توسعه دهندگان خود رعایت کنیم.

نکته 1: قلاب های خود را لاغر و متوسط ​​نگه دارید

نکته ای که باید به آن توجه داشته باشید این است که این قلاب ها همچنان کدهایی را که در یک رشته اجرا می شوند فراخوانی می کنند. مگر اینکه چیزی را در تماس تلفنی خود فعال کنید که کار را در برخی از فرایندهای پس زمینه یا سرویس های دیگر آغاز کند ، API همچنان این کد اضافی را اجرا می کند (هنگامی که قلاب فعال می شود). این بدان معناست که ما باید تمام تلاش خود را به کار ببریم تا هرگونه کد تماس را بی عیب و نقص نگه داریم. کد تماس طولانی مدت نقاط پایانی یا کل API را کند می کند.

نکته 2: هر تماس تلفنی را جداگانه و اشکال زدایی را ساده کنید

با این حال ، با نحوه طراحی این ساختار ، افزودن و حذف توابع تماس برای قلاب های شما آسان است و اشکال زدایی نیز به همین سادگی است. پیدا کنید که کدام تماس تلفنی متخلف است (شاید هر کدام از اطلاعات تماس تلفنی اطلاعاتی را ثبت کنند) و دریابید که در کجا گیر کرده است. سپس به سادگی آن را مجبور به عضویت در قلاب نکنید تا زمانی که اشکال برطرف نشود یا از طریق کد تماس کار نکند ، مجدداً چیزی را در کد پایانی/API لمس نکنید و مانع از اجرای کد API خود در تولید شوید.

نکته 3: در مورد عملکرد فکر کنید و از قلاب سوء استفاده نکنید

همچنین مهم است که مراقب تعداد تماس های تلفنی باشید که به قلاب خود وصل می کنید. تعداد انگشت شماری از تماس های سریع خوب است ، اما 100 تماس تلفنی در یک قلاب که هر یک از آنها یک ثانیه زمان می برد ، واقعاً می تواند بر API شما تأثیرگذار باشد. ما خواستار تماس های API سریع هستیم و هر تماس تلفنی می تواند به راحتی زمان پاسخ را بکشد. مجدداً ، اگر تماس تلفنی را آهسته می بینید ، کار را به یک فرایند پیش زمینه یا سیستم صف منتقل کنید تا بعداً توسط سرویس دیگری انجام شود. من اغلب از مشاغلی در سیستم هایی مانند Laravel برای انجام چنین کارهایی استفاده می کنم. شاید کار کاربر را به a اضافه کنید صف کار لاراول و با پردازش API ادامه دهید.

در نهایت ، مطمئن شوید که با توسعه دهندگان خود که ممکن است از این قلاب ها استفاده می کنند در ارتباط باشید. متداول است که توسعه دهندگان از قلاب های شما و نوشتن تماس های تلفنی همان افرادی نیستند که در ابتدا این قلاب را در API ایجاد کرده اند. با بالغ شدن API شما ، ممکن است درخواست هایی برای افزودن قلاب های بیشتر در مکان های مختلف و با دقت بیشتر مشاهده کنید. آنها ممکن است از قلاب های قبل/بعد درخواست کنند که می تواند برای انجام اقدامات قبل از قرار دادن کاربر و همچنین بعد از آن استفاده شود. آنها همچنین ممکن است بخواهند اطلاعات اضافی به تماس گیرندگان ارسال شود (به عنوان مثال نه تنها نام و سن آنها ، بلکه شناسه جدید کاربر درج شده). این درخواست ها را به عنوان یک نشانه خوب بدانید که توسعه دهندگان شما مکانیسم مفید را می دانند و پتانسیل گسترش تأثیر API خود را در سیستم های مرتبط می بینند. واقعاً داشتن سیستمی بسیار آسان است که بتوانید یک قطعه کد کوچک را “متصل” کرده و اجرا کنید تا تأثیر زیادی داشته باشد.

با این رویکرد ، آسمان محدودیتی است که می توانید API خود را انجام دهید. این امر می تواند در حالی انجام شود که جریان اصلی نقطه پایانی شما هنگام برخورد با سیستم های دیگر روشن و عاری از سر و صدا باشد.

نتیجه

در این مقاله ، ما در مورد چگونگی قلاب ها/اقدامات و نحوه استفاده از آنها بحث کردیم. ما چند کد PHP مثال زدیم که می توانید در PHP API خود برای پیاده سازی “hooking” و نحوه استفاده از callback برای اتصال به آن قلاب استفاده کنید. ما همچنین در مورد افزودن قلاب در سطح API عمومی (در سطح جهانی برای همه درخواست ها) و همچنین در نقاط پایانی بحث کردیم. علاوه بر این ، ما همچنین کمی در مورد برخی از اشکالات این سیستم صحبت کردیم و این ایده خوبی است که تماس های تلفنی خود را لاغر و متوسط ​​نگه دارید. اما در صورت داشتن تماس طولانی مدت ، ما چند استراتژی برای برخورد با چنین فرایندهایی ذکر کردیم تا از تأثیر آنها بر خط لوله API شما جلوگیری شود.

اگر این سیستم را پیاده سازی کنید ، شما نیز می توانید برخی از بزرگترین عملکردهایی را که جامعه وردپرس (و به طور کلی برنامه نویسان) سالها از آن لذت برده اند ، بدست آورید. همچنین می توانید زمان و سردردهای زیادی را از مجبور به تغییر مستقیم کد API خود نجات دهید و به جای آن می توانید بر روی کد کوچک تماس مجدد تمرکز کنید. همچنین می توانید تماس های تلفنی که ممکن است یکپارچه با سیستم های دیگر باشد را اضافه و حذف کنید. همه این قابلیتها – و نه یکبار مجبور به بازنشر کد خط لوله API خود شوید! این معامله بسیار خوبی است ، درست است؟ با استفاده از این سیستم ، من توانستم چند ادغام ساده را در یک روز انجام دهم ، و اکنون شما نیز می توانید این کار را انجام دهید.

ممنون که خواندید!