ammit-php / ammit
[DDD] 稳定的框架无关命令解析器
Requires
- php: >=7.0
- psr/http-message: ^1.0
Requires (Dev)
- atoum/atoum: ~2.8
- atoum/stubs: ~2.5
- sensiolabs/security-checker: ^4.0
This package is not auto-updated.
Last update: 2024-09-11 17:47:02 UTC
README
# Ammit一个轻量级、稳定且框架无关的命令解析器库
目前正在接受实战测试(尚未标记为1.0.0)
一个命令是一个简单的、有良好命名的DTO,反映了用户的意图。
因此它应该是不可变的。
- RegisterUserCommand
- DisableUserCommand
- BookCargoCommand
库的功能?
- 它提供了一个辅助工具,可以轻松地从PSR-7 HTTP请求(或CLI输入)中提取标量数据,以实例化一个不可变的命令。
- 它允许实现干净的命令(没有公共字段)。
- 它设计为简单的UI验证框架,无需依赖。
- 它设计用来简化UI验证与领域验证的关注点分离
如何使用它?
composer require ammit-php/ammit
示例
实现一个RegisterUserCommandResolver
,它将PSR-7 ServerRequestInterface
映射到RegisterUserCommand
。在创建RegisterUserCommand
之前,它将执行UI验证。
RegisterUserController.php
$registerUserCommandResolver = new RegisterUserCommandResolver(); try { $command = $registerUserCommandResolver->resolve($request); } catch (AbstractNormalizableCommandResolverException $e) { // Return a JSON error following jsonapi.org's format // @see https://jsonapi.fullstack.org.cn/examples/#error-objects-basics return JsonResponse::fromJsonString( json_encode( $e->normalize() ), 406 ); } try { $this->userService->registerUser($command); } catch(DomainException $e) { // ... } // ...
RegisterUserCommandResolver.php
/** * Resolve a PSR-7 Request into a RegisterUserCommand (Data Transfer Object) */ class RegisterUserCommandResolver extends AbstractPureCommandResolver { /** * @inheritdoc */ public function resolve(ServerRequestInterface $request): RegisterUserCommand { $commandConstructorValues = $this->resolveRequestAsArray($request); // We are using variadic function here (https://wiki.php.net/rfc/variadics) return new RegisterUserCommand(...$commandConstructorValues); } /** * @inheritDoc */ protected function validateThenMapAttributes(ServerRequestInterface $request): array { // $id = $_GET['id'] $id = $this->queryStringValueValidator->mustBeString( $request, 'id' ); // $firstName = $_POST['firstName'] $firstName = $this->attributeValueValidator->mustBeString( $request, 'firstName' ); // $lastName = $_POST['lastName'] $lastName = $this->attributeValueValidator->mustBeString( $request, 'lastName' ); // $email = $_POST['email'] $email = $this->attributeValueValidator->mustBeString( $request, 'email' ); // Will be injected directly in RegisterUserCommand::__construct(...$args) // as variadic function $commandConstructorValues = [ $id, $firstName, $lastName, $email ]; return $commandConstructorValues; } }
在Symfony中使用它:https://symfony.ac.cn/doc/current/request/psr7.html
在Laravel中使用它:待定
公共API
纯扩展AbstractPureCommandResolver
实用扩展AbstractPragmaticCommandResolver
库不做什么?
- 它不是设计来替代Symfony Form Component的。
- 它不是设计来创建复杂验证的。它的目标是验证简单的标量。然而,它仍然允许"实用"的复杂UI验证,用于原型设计/快速应用程序开发。
- 它不是设计来使用PHP反射的。它只意味着使用命令构造函数。
为什么?
我们曾经使用Symfony Form Component将HTTP请求映射并验证到我们的命令。
但这太复杂了,并且hacky。并且太容易将我们的领域验证放入FormType。然后“忘记”将其放回我们的领域。
此外,我们希望预见不可变类。
它是如何工作的?
它内部使用\Closure
,以便能够捕获所有\Exception
。否则,它只会显示一个验证问题。而我们希望像表单一样一次性看到所有验证问题。
实用主义?
您可能需要在UI中放置一些领域验证。有时我们在原型设计时需要进行一些快速应用程序开发。并且知道我们将在不久的将来偿还我们的技术债务。
使用Ammit,您将使用我们的AbstractPragmaticCommandhenResolver
(实用)而不是我们的AbstractPureCommandResolver
(纯)辅助工具。它将允许您使用更复杂的验证,例如示例中的uuid
验证。
$email = $attributeValueValidator->mustBeUuid( $request, 'id' );
缺少验证。您仍然可以注入自己的。
想要贡献?
阅读UBIQUITOUS_LANGUAGE_DICTIONARY.md
初始化 Docker 容器:docker-compose up -d
Composer 安装:docker-compose run --rm composer install
使用容器:docker/bin/php -v
(首先执行 chmod +x docker/bin/php
)
添加单元测试后:docker/bin/php bin/atoum
Ammit?
Ammit 是一位古代埃及女神,与心脏称重有关。她吞噬那些被认为不够纯洁,无法继续前往奥西里斯和永生之旅的人类灵魂。