kairos-project / api-controller
kaivos项目API的部分控制器
Requires
- psr/http-message: ^1
- psr/log: ^1
- symfony/event-dispatcher: ^4.1
Requires (Dev)
- infection/infection: ^0.8.2
- kairos-project/tests: ^1@dev
- phpmd/phpmd: ^2.6
- phpmetrics/phpmetrics: ^2.3
- phpunit/phpunit: ^7.2
- sebastian/phpcpd: ^4
- squizlabs/php_codesniffer: ^3.3
This package is not auto-updated.
Last update: 2024-09-15 05:18:26 UTC
README
Kairos API控制器元素
1) 主题
由于kaivos项目API基于组件之间事件的调度以产生顺序数据处理,API控制器负责请求处理和结果分发。
基于HTTP定义,API控制器必须能够处理这些定义的事件
- 使用GET方法获取项目列表
- 使用GET方法获取特定项目
- 使用POST方法发布特定项目
- 使用PUT方法替换特定项目
- 使用PATCH方法更新特定项目部分
- 使用DELETE方法删除特定项目
根据REST规范,一般理解的使用和大型服务所需的处理能力,API控制器必须能够处理特定的重载POST。根据其逻辑方式,这种重载方法可以在数据处理工作流配置中脚本化,无需由控制器直接处理。
除了基本的HTTP规范方法和它们在REST API中的使用外,控制器必须提供将一些高级、自定义或规范扩展的动词纳入的能力。例如,可以使用LINK和UNLINK方法,在库用户的故事中,并提供将这些功能注入系统的方法和正确描述。
为了提供有价值的系统,逻辑必须保证输出格式的正确性,无论处理是否失败。为此,为了确保这种安全操作,将执行两级事件分发。首先将构造数据并返回初始事件中的结果,或将异常注入到该事件中,异常包含错误代码。第二个将事件结果重构为格式化的输出,由控制器返回。在这种情况下,结果必须是有效的响应类或任何能够被系统过滤器处理的数据。此功能允许最终用户根据其需求扩展框架。
2) 类架构
API控制器架构必须遵循框架的使用和高级用户的可扩展性需求。一个特定的考虑是现有框架的默认控制器和PHP语言关于多重继承的自然限制。
让我们通过一个简单的例子来开发这个特定的案例研究:作为一个开发者,你希望在项目中使用API控制器并扩展其中包含的功能。你将面临的第一项困难是选择控制器类和框架系统之间的集成方式。如果框架提供了一个高级控制器,并且它符合你的需求,那么在这次实现中扩展此控制器将是逻辑的,甚至是必要的,然后你可以从框架功能中获得好处。
如果我们假设API控制器是一个简单的类或一个抽象类,你将面临单继承限制。这来自于无法同时扩展你的框架控制器和API控制器的事实。幸运的是,PHP语言通过使用特质系统提供了一种解决这个特定问题的替代方案。
然后我们将假设特质系统是API控制器逻辑的实现地点。因此,控制器将必须是一个更复杂系统的一部分,必须确保实现接口,然后将其用于第三方库或现有代码部分。因此,为了确保接口实现,必须存在一个以PHP接口元素形式存在的合同,并必须描述每个类方法的输入和输出。
3) 依赖描述和使用到元素中
在编写本文档时,API控制器被设计为具有三个生产依赖项,如下所示
- psr/http-message
- psr/log
- symfony/event-dispatcher
3.1) psr/http-message
根据PHP标准建议第7号,HTTP消息(如请求和响应表示)必须实现一个指定的接口。这些接口由psr/http-message包定义,允许任何框架使用此库。顺便说一下,至少API控制器的输入必须遵循PSR7语法。
3.2) psr/log
首先,也许是一件软件必须考虑的最重要的事情是安全和调查设施。
调查设施的一部分是开发社区普遍认同的最佳实践,它允许接收有关内部软件流程的信息。
关于安全部分,必须考虑OWASP十大威胁。
根据PHP标准建议第3号,记录组件必须实现一个指定的接口。该接口由psr/log包定义,并允许任何框架使用此库。
3.3) symfony/event-dispatcher
API控制器系统被设计为易于扩展,并将实现一个事件调度系统,允许按优先级附加和分离逻辑。
在编写本文档时,事件管理建议的草案正在研究。但这个草案的状态不允许立即集成,我们必须在技术实现方面做出选择。
由于当前开发人员对它的理解以及提供的功能,Symfony事件调度器是一个好的选择。但我们必须记住,将来有可能改变它。
4) 实现规范
API控制器实现了一个带有两个参数的执行方法,这些参数接收当前请求和基本事件名称。名称本身用于区分请求行为,如本文档第1章所述。
4.1) 依赖注入规范
实例将直接在构造函数中直接接收记录实例和事件调度器实例。
在配置级别,实例还可以接收一个进程和一个响应前缀,在处理逻辑期间用于计算派发的事件。这些前缀分别为'process_'和'response_',分别用于进程和响应事件。
4.2) 执行方法算法
Assuming request from parameters. Assuming event name from parameters. Assuming logger in properties. Assuming event dispatcher in properties. Computing process event name based on the parameter event name following the format '{processing_prefix}{event_name}'. Log request method, computed event name and controller instance name at debug level. Instantiating new process event and populate it with the parameter request. Start fail-safe operation. Dispatching the process event over the stored event dispatcher with the computed process event name. In case of failure, hydrate the process event with the resulting exception and log it. End fail-safe operation. Instantiating new response event, hydrated with the processing event response part. Computing response event name based on the parameter event name following the format '{response_suffix}{event_name}'. Log computed event name at debug level. Dispatching the response event over the stored event dispatcher with the computed response event name. Returning the response event result.
4.3) 事件规范
除了特定事件逻辑之外,每个事件都必须符合基本事件调度库的事件。顺便说一下,事件调度开关将由初始事件逻辑保证。
4.3.1) 进程事件
进程事件负责请求和响应的处理。因此,它必须至少实现'getRequest'、'setResponse'和'getResponse'方法。原始请求本身将在构造函数级别通过依赖注入提供。
此外,过程事件必须提供存储和检索在过程执行期间使用的任何参数的能力,这些参数由附加到已分发事件的监听器集提供。将实现包括 'setParameter'、'getParameter'、'setParameters'、'getParameters'、'hasParameter' 等方法,以与内部命名参数包进行交互。
4.3.2) 响应事件
响应事件负责响应转换,以确保符合给定的格式。它将实现 'setResponse' 和 'getResponse' 方法,允许更改原始响应元素。
与过程事件一样,响应事件也将提供参数存储功能。
5) 使用方法
5.1) 基本使用
use KairosProject\ApiController\Controller\ApiController; use Symfony\Component\EventDispatcher\EventDispatcher; // Instanciating event dispatcher $eventDispatcher = new EventDispatcher(); $eventDispatcher->addListener('process_gets', $listener); $eventDispatcher->addListener('response_gets', $listener); $controller = new ApiController( $eventDispatcher, $logger ); $response = $controller->execute($request, 'gets');
5.2) 特定事件名称
use KairosProject\ApiController\Controller\ApiController; use Symfony\Component\EventDispatcher\EventDispatcher; // Instanciating event dispatcher $eventDispatcher = new EventDispatcher(); $eventDispatcher->addListener('specific_process_gets', $listener); $eventDispatcher->addListener('specific_response_gets', $listener); $controller = new ApiController( $eventDispatcher, $logger, 'specific_process_', 'specific_response_' ); $response = $controller->execute($request, 'gets');
5.3) 简单继承
namespace My\Namespace; use KairosProject\ApiController\Controller\ApiController; use Psr\Http\Message\ServerRequestInterface; class Controller extends ApiController { public function execute( ServerRequestInterface $request, string $eventBaseName ) { return parent::execute($request, $eventBaseName); } }
5.4) 高级继承
namespace My\Namespace; use KairosProject\ApiController\Controller\ApiControllerInterface; use KairosProject\ApiController\Traits\ExecutionTrait; class Controller extends AnotherController implements ApiControllerInterface { use ExecutionTrait; }
5.5) 在末尾分配响应
如果没有人自行分配响应,为了连接过程逻辑和响应逻辑,ApiController模块提供了一个名为ResponseHydratorListener的组件,可以在过程的末尾插入。此组件接受一个参数名作为参数,允许指定哪个事件参数将被用作响应。
use KairosProject\ApiController\Controller\ApiController; use Symfony\Component\EventDispatcher\EventDispatcher; use KairosProject\ApiController\Listener\ResponseHydratorListener; // Instanciating event dispatcher $eventDispatcher = new EventDispatcher(); $eventDispatcher->addListener('process_gets', $listener); $eventDispatcher->addListener('process_gets', new ResponseHydratorListener('my_parameter')); $eventDispatcher->addListener('response_gets', $listener); $controller = new ApiController( $eventDispatcher, $logger ); $response = $controller->execute($request, 'gets');