設計應用程序編程接口(API)可能是一項具有挑戰性的努力。良好的API具有簡單易用的簡單接口。在這個簡單的接口背後可以是許多複雜的系統交互,這些交互實際上可能會使原本明確定義的端點任務的水域變得混亂。隨著時間的流逝,可能會要求開發人員為現有終點“了解”其他業務邏輯。然後,在您不知不覺中,作為主要流程的一部分,一個API調用正在與十幾個系統進行交互。
>如果我們可以開發一個簡單的管道,但是可以在以後添加其他任務而不掩蓋主流量的情況下添加其他任務,那不是很好嗎?本文將向您展示如何從WordPress和編程中調整一個想法,以使您的API能夠進行更強大的互動。
>鉤背後的想法並不是什麼新鮮事物,也不是WordPress發明的。但是,WordPress在其服務器端處理生命週期期間實現了它們,做得很好。在我看來,這種鉤子的使用可能是平台擁有的最大功能。使用這些掛鉤,用戶可以編寫自己的功能(無論是插件還是主題),可以將其連接到WordPress中,並在需要時運行您想要的任何代碼。您需要更改發送給用戶的標頭嗎?沒問題:進入WP_headers事件,您可以在發現合適的情況下更改標題。
如果端點是用於創建用戶的終點,我們可以專注於在數據庫中創建該用戶記錄,並在此過程中召集在此過程中正在偵聽的任何人。也許在創建用戶記錄之後,我們發出了一個事件,上面寫著“任何人都在聽此操作,我只是創建了一個用戶,這是他們的信息”。也許某些回調功能已經訂閱了該事件,並且正在聽,或者也沒有。該活動並不真正在乎。
>使用此系統,我們可以將API呼喚到可能在以後的某個時間編寫的代碼。我們可以做到這一點,而無需觸摸API端點代碼本身。為了證明這可能是如何工作的,讓我們更改齒輪,並展示如何以PHP API開始實現這一目標的基本機制。請記住,當我們在此處使用PHP時,我們實際上可以使用其他語言在Web應用程序中實現類似的邏輯。
構建基本機制
為了開始,我們需要能夠添加一個鉤子/操作(從現在開始我將其稱為“鉤子”)。我們還需要能夠卸下鉤子並觸發鉤子的能力。定義這些機制後,我們只需要確保它們包含在API中,然後在API中找到可能需要調用這些鉤子的位置即可。以下是我們可能想設置此的一種方式。
>現在我們已經創建了hooks.php文件,我們只需要將其包含在我們的API中,以便可以看到這些功能。完成此操作後,這只是使用DO_HOOK將鉤子插入我們的API的問題。
<span>// Global array which will hold all of our hooks </span><span>// We will reference this array in each function to add/remove/call our hooks </span><span>// The code below should also be seen by any callbacks we write for the system later. </span><span>$hooks = []; </span> <span>// Below are global functions that can be seen from our API code </span><span>// The add_hook method will allow us to attach a function (callback) to a given event name </span><span>function add_hook($event_name, $callback) { </span> <span>global $hooks; </span> <span>if ($callback !== null) { </span> <span>if ($callback) { </span> <span>// We can set up multiple callbacks under a single event name </span> <span>$hooks[$event_name][] = $callback; </span> <span>} </span> <span>} </span><span>} </span> <span>// Super easy to implement, we remove the given hook by its name </span><span>function remove_hook($event_name) { </span> <span>global $hooks; </span> <span>unset($hooks[$event_name]); </span><span>} </span> <span>// When we want to trigger our callbacks, we can call this function </span><span>// with its name and any parameters we want to pass. </span><span>function do_hook($event_name, ...$params) { </span> <span>global $hooks; </span> <span>if (isset($hooks[$event_name])) { </span> <span>// Loop through all the callbacks on this event name and call them (if defined that is) </span> <span>// As we call each callback, we given it our parameters. </span> <span>foreach ($hooks[$event_name] as $function) { </span> <span>if (function_exists($function)) { </span> <span>call_user_func($function, ...$params); </span> <span>} </span> <span>} </span> <span>} </span><span>} </span>
>
<span>// Global array which will hold all of our hooks </span><span>// We will reference this array in each function to add/remove/call our hooks </span><span>// The code below should also be seen by any callbacks we write for the system later. </span><span>$hooks = []; </span> <span>// Below are global functions that can be seen from our API code </span><span>// The add_hook method will allow us to attach a function (callback) to a given event name </span><span>function add_hook($event_name, $callback) { </span> <span>global $hooks; </span> <span>if ($callback !== null) { </span> <span>if ($callback) { </span> <span>// We can set up multiple callbacks under a single event name </span> <span>$hooks[$event_name][] = $callback; </span> <span>} </span> <span>} </span><span>} </span> <span>// Super easy to implement, we remove the given hook by its name </span><span>function remove_hook($event_name) { </span> <span>global $hooks; </span> <span>unset($hooks[$event_name]); </span><span>} </span> <span>// When we want to trigger our callbacks, we can call this function </span><span>// with its name and any parameters we want to pass. </span><span>function do_hook($event_name, ...$params) { </span> <span>global $hooks; </span> <span>if (isset($hooks[$event_name])) { </span> <span>// Loop through all the callbacks on this event name and call them (if defined that is) </span> <span>// As we call each callback, we given it our parameters. </span> <span>foreach ($hooks[$event_name] as $function) { </span> <span>if (function_exists($function)) { </span> <span>call_user_func($function, ...$params); </span> <span>} </span> <span>} </span> <span>} </span><span>} </span>
上面的代碼是我們如何添加新用戶的過度簡單和普遍的視圖。這個想法是,如果某人打電話給我們的API /Adduser端點,他們最終將在此功能中得出此功能,從而將用戶的名稱和年齡從已發布的數據中提取出來。我們首先檢查以確保他們發布(作為適當的休息規則規定),然後嘗試將用戶插入用戶表中。
接下來,如果成功插入了用戶,我們想調用鉤子,以使任何創建用戶的代碼偵聽(這類似於用其他語言提出事件)。
幾個月後,我們讓我們的營銷部門堅持認為,當創建新用戶時,應將電子郵件發送給用戶的詳細信息。我們可能傾向於將助手功能寫入API,然後從此端點代碼中調用它。太好了……如果這就是要求的。但是,如果支持團隊後來來到您身邊,並希望您還將用戶添加到他們的Zendesk系統中。因此,您還編寫另一個功能,並將其撥打到此端點。
接下來,您知道,此端點不僅是將用戶添加到我們的網站數據庫中,而且還呼籲發送電子郵件,將用戶添加到Zendesk,Jira和Microsoft Cloud,然後處理其成功/失敗結果。所有這些其他東西確實從將用戶添加到我們的數據庫的清晰點中。我們想調用一個事件,並讓其他代碼在創建用戶並做自己的事情時聆聽 - 而無需我們修改此端點。也許沒有其他服務在乎添加新用戶,因此沒有人被要求做任何事情。終點不必關心。很棒,對
>讓我們以鉤子的名字來繼續我們的榜樣。這是所有回調代碼都需要使用的名稱。同樣,其他語言將此設置稱為“事件”,因此請務必用給定的語言查找它以了解更多信息。
我們將調用hook add_user。簡單而直截了當,你不覺得嗎?一旦有名,我們就可以決定要在哪裡稱呼此鉤子。我認為成功插入後是個好主意:
<span>// POST endpoint for adding a user (part of a larger API class) </span><span>public function addUser($name, $age) { </span> <span>if ($this->request->method === 'post') { </span> <span>try { </span> <span>$this->db->insert('users', ['name' => $name, 'age' => $age]); </span> <span>return new Response(200, 'User created successfully!'); </span> <span>} catch (Exception $e) { </span> <span>// Oops, something went wrong. </span> <span>// Do some logging or whatever. </span> <span>} </span> <span>} </span> <span>// If not a POST request, return http status 400 </span> <span>return new Response(400, 'Bad request'); </span><span>} </span>
>現在,我們可以有數十個回調函數收聽添加_user鉤或根本沒有。也許我們有一個回調,負責將用戶插入Zendesk,而另一個將插入姓名和年齡並為營銷生成電子郵件。只要可以在API項目中看到hooks.php代碼,就可以在代碼庫中的其他地方生活。我通常將回調函數放在單獨的文件中,並將該文件也包括在API中。以下是回調的一個示例,現在可以利用我們創建的這個新鉤子:
最佳實踐 >
>請注意您在鉤子上附加多少個回調也很重要。少數幾個快速回調是可以的,但是單個掛鉤上的100個回調,每秒鐘執行一秒鐘確實可以阻止您的API。我們需要快速的API調用,並且每個回調都可以輕鬆拖動響應時間。同樣,如果您發現回調速度慢,請將任務扔到背景過程或隊列系統中,以後將由另一個服務撿起。我經常在Laravel之類的系統中使用工作來處理此類任務。也許將用戶任務添加到Laravel作業隊列中,然後繼續進行API處理。 使用這種方法,天空是您可以擁有的API所做的限制。在與其他系統打交道時,這一切都可以實現,同時保持端點的主要流量清晰,沒有噪音。 結論 如果您實現了此系統,則您也可以獲得WordPress社區(以及總體程序員)多年來所享受的一些最大功能。您還可以節省很多時間和頭痛,從必須直接修改API代碼,並且可以專注於小回調代碼。您還可以添加和刪除可能與其他系統的整個集成在一起的回調。所有這些功能 - 不必重新發布您的API管道代碼!這是一個很好的交易,對吧?有了這個系統,我一天都設法進行了一些簡單的集成,現在您也可以做到。 感謝您的閱讀! >如何為我的PHP API管道創建掛鉤?對於您的PHP API管道,涉及定義可以執行自定義代碼的代碼中的特定點。這通常是使用事件和聽眾完成的。當發生特定事件時,觸發相應的偵聽器,執行自定義代碼。這使您可以在運行時修改應用程序的行為,提供高度的靈活性和適應性。 PHP與API設計的其他語言相比如何? > >如何處理API中的錯誤? >我如何提高API的性能? <span>// Global array which will hold all of our hooks
</span><span>// We will reference this array in each function to add/remove/call our hooks
</span><span>// The code below should also be seen by any callbacks we write for the system later.
</span><span>$hooks = [];
</span>
<span>// Below are global functions that can be seen from our API code
</span><span>// The add_hook method will allow us to attach a function (callback) to a given event name
</span><span>function add_hook($event_name, $callback) {
</span> <span>global $hooks;
</span>
<span>if ($callback !== null) {
</span> <span>if ($callback) {
</span> <span>// We can set up multiple callbacks under a single event name
</span> <span>$hooks[$event_name][] = $callback;
</span> <span>}
</span> <span>}
</span><span>}
</span>
<span>// Super easy to implement, we remove the given hook by its name
</span><span>function remove_hook($event_name) {
</span> <span>global $hooks;
</span>
<span>unset($hooks[$event_name]);
</span><span>}
</span>
<span>// When we want to trigger our callbacks, we can call this function
</span><span>// with its name and any parameters we want to pass.
</span><span>function do_hook($event_name, ...$params) {
</span> <span>global $hooks;
</span>
<span>if (isset($hooks[$event_name])) {
</span> <span>// Loop through all the callbacks on this event name and call them (if defined that is)
</span> <span>// As we call each callback, we given it our parameters.
</span> <span>foreach ($hooks[$event_name] as $function) {
</span> <span>if (function_exists($function)) {
</span> <span>call_user_func($function, ...$params);
</span> <span>}
</span> <span>}
</span> <span>}
</span><span>}
</span>
我們可以在哪裡放置這些鉤子?
在上面的代碼中,我們在單個端點中使用鉤子演示。僅在調用 /adduser端點時才觸發此鉤子,並且只有在插入成功後才觸發。但這不是您唯一可以使用這些鉤子的地方。也許您在API類中有一些路由代碼,可以通過檢查API密鑰是否有效,或者您甚至收到某種類型的請求。 >由於您可以在多個位置使用此機制,因此您甚至可以在API端點的開頭,中間和結尾處使用鉤子。您還可以在處理請求的整個API生命週期的各個點上有鉤子。這實際上取決於您在插入這些do_hook呼叫的位置上的設計。
>現在讓我們介紹一些最佳實踐,以供您和您的開發人員遵循。
>提示1:保持鉤子瘦弱和平均
>提示2:使每個回調隔離且易於調試
提示3:考慮性能,不要濫用鉤子
提示4:與您的開發社區保持聯繫
最後,確保您與可能使用這些掛鉤的開發人員保持聯繫。通常,開發人員使用您的鉤子和編寫回調,與創建API中創建鉤子的人並不是一開始。隨著API的成熟,您可能會開始看到在不同地方添加更多鉤子和更精細的粒度的請求。他們可能會要求在插入用戶之前和之後插入用戶之前/之後的掛鉤之前/之後。他們還可能要求將其他信息傳遞給他們的回調(不僅是他們的名稱和年齡,還包括插入用戶的新ID)。以這些要求為一個好兆頭,表明您的開發人員發現該機制有用,並看到擴大API在相關係統中的影響的潛力。擁有一個非常容易“掛接”並執行一小塊代碼以產生巨大影響的系統真的感覺很好。
>
關於靈活的API設計和PHP掛鉤的常見問題(常見問題解答)
> PHP API管道中掛鉤在PHP API管道中的重要性是什麼?它們允許開發人員在程序執行中的特定點插入自定義代碼,而無需更改核心代碼。這使得在不破壞整個系統的情況下更容易添加,修改或刪除功能。鉤子本質上是由特定動作觸發的事件,可以用來以乾淨且有條理的方式擴展應用程序。
>>設計靈活的API的最佳實踐是什麼?幾種最佳實踐。首先,保持API簡單而直觀非常重要,從而使開發人員易於理解和使用。其次,應將API設計為可擴展的,從而允許添加新功能而不會破壞現有功能。第三,提供清晰,全面的文檔至關重要,幫助開發人員了解如何有效使用API。最後,使用標準的HTTP方法和狀態代碼可以使API更容易預測,更易於使用。
> > API設計中有哪些共同的挑戰,如何解決?
API設計可以提出一些挑戰,包括確保一致性,管理版本控制和有效處理錯誤。一致性可以通過遵循既定的慣例和標準來維持。可以通過在API URL或請求標頭中包含版本編號來管理版本控制。應該優雅地處理錯誤,提供清晰且有用的錯誤消息,以幫助開發人員診斷和解決問題。 >
>我如何確保API的安全性?措施。這包括使用安全通信協議,例如HTTP,實施身份驗證和授權機制,以及驗證和消毒輸入數據以防止注射攻擊。定期的安全審核和更新還可以幫助識別和修復潛在的漏洞。 >測試您的API涉及向API端點和API的請求驗證響應。這可以使用郵遞員等工具手動完成,也可以自動使用測試框架來完成。測試API的各個方面,包括功能,性能和安全性很重要。
>處理API中的處理錯誤涉及返回適當的HTTP狀態代碼和錯誤消息。這有助於開發人員了解出了什麼問題以及如何解決問題。記錄錯誤和分析的錯誤也很重要。
以上是靈活的API設計:為您的PHP API管道創建鉤子的詳細內容。更多資訊請關注PHP中文網其他相關文章!