设计应用程序编程接口(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中文网其他相关文章!