ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Laravel Actions 监听器入口 `asListener`:在 Coolify 中将 Action 无缝接入领域事件

Laravel Actions 监听器入口 `asListener`:在 Coolify 中将 Action 无缝接入领域事件 Laravel Actions 监听器入口asListener在 Coolify 中将 Action 无缝接入领域事件【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku Netlify that lets you easily deploy static sites, databases, full-stack applications and 280 one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolify本文对应仓库内.cursor/skills/laravel-actions/references/listener.md文档的深度展开。它聚焦于 Lorisleiva Laravel Actions 的事件监听器入口asListener如何让一个以handle(...)承载业务逻辑的 Action 同时充当 Laravel 事件监听器如何在EventServiceProvider中注册事件映射以及如何用Event::fake()编写聚焦的监听器测试。Coolify 自身大量使用lorisleiva/laravel-actions见 composer.json 中lorisleiva/laravel-actions: ^2.10.2并配合app/Events、app/Listeners形成了事件驱动的内部通信骨架读完本文即可在你的 Laravel 项目含 Coolify 二次开发中照此落地。一、为什么要为 Action 增加「监听器入口」Lorisleiva Laravel Actions 的核心思想是把某个用例use case的全部逻辑收敛进一个 Action 类让同一个 Action 通过不同入口装饰器服务于不同传输层。.cursor/skills/laravel-actions/SKILL.md给出了四种常用入口asControllerHTTP、asJob队列、asListener事件、asCommandCLI外加直接以对象方式调用。这套约定的价值在于入口与业务解耦领域/业务逻辑只写一份统一放在handle(...)HTTP 响应、队列重试、事件适配等传输层关注点放在各as*适配方法中同一用例可被路由、队列、事件、命令行同时复用且可被整体 fake 与断言。Coolify 正是这一模式的实践者app/Actions下按Server、Database、Service、Application、Proxy等领域组织了几十个 Action例如 RunCommand 中handle(Server $server, $command)封装远程命令执行StartService 通过configureJob(JobDecorator $job)声明队列又通过StopService::run(...)以对象入口复用其他 Action。而事件入口则让这些 Action 可以在事件发生时被 Laravel 自动回调形成事件到达 → Action 执行业务的统一链路。二、asListener机制事件负载如何映射到handle参数参考文档 listener.md 明确了三点职责范围说明监听器执行时如何把事件负载映射为handle(...)的参数描述asListener(...)的回退行为fallback与适配角色给出在 ServiceProvider 中注册事件映射的示例并强调测试应聚焦于分发与 Action 交互。装饰器与回退语义当 Action 被注册为事件监听器后框架经由包的ListenerDecorator执行。核心语义是场景行为类中定义了asListener(Event $event)装饰器调用asListener由它负责解包事件并把参数转交handle(...)类中未定义asListener回退到直接调用handle(...)因此asListener是一个可选的适配层当事件对象结构与handle(...)的签名不一致例如事件携带的是多个强类型领域对象而handle期望逐个参数接收时asListener负责翻译当二者天然一致时即使不写asListener监听器也能工作。推荐模式在EventServiceProvider或项目等效位置注册 Action 为事件监听器用asListener(Event $event)做事件适配把核心逻辑委托给handle(...)绝不在asListener中重复实现业务。三、最小完整示例Action 作为事件监听器参考文档给出的例子属于打车派单领域TaxiRequested事件 →SendOfferToNearbyDriversAction我们原样继承并逐行说明。1. 定义 ActionhandleasListenerclass SendOfferToNearbyDrivers { use AsAction; public function handle(Address $source, Address $destination): void { // 核心业务逻辑查找附近司机、发送报价…… } public function asListener(TaxiRequested $event): void { $this-handle($event-source, $event-destination); } }要点use AsAction;来自Lorisleiva\Actions\Concerns\AsAction是类获得全部入口能力的前提handle(...)的参数是业务级强类型参数这里为两个Address它不感知事件的存在便于直接复用、单测asListener(TaxiRequested $event)只做一件事从事件对象中取出$event-source、$event-destination转发给handle(...)。2. 注册事件到监听器的映射事件与监听器的绑定必须在框架层面显式声明。在 Laravel 中通过服务提供者的$listen属性完成// app/Providers/EventServiceProvider.php protected $listen [ TaxiRequested::class [ SendOfferToNearbyDrivers::class, ], ];当TaxiRequested::dispatch(...)被调用时Laravel 事件分发器会实例化SendOfferToNearbyDrivers随后ListenerDecorator介入优先调用asListener缺省则回退handle。3. 聚焦的监听器测试监听器测试不关注handle内部的业务细节那应由handle的独立测试覆盖而应验证事件分发后确实触发了 Action这条链路的完整性use Illuminate\Support\Facades\Event; Event::fake(); TaxiRequested::dispatch($source, $destination); Event::assertDispatched(TaxiRequested::class);Event::fake()阻止真实监听器副作用的发生随后用Event::assertDispatched断言事件确实被分发。若要进一步断言 Action 与事件之间的交互可结合.cursor/skills/laravel-actions/references/testing-fakes.md中介绍的 Action 假件MyAction::fake()、assertDispatched、shouldRun等形成分发 交互的双层验证。四、在 Coolify 中事件与监听器的仓库级参照以本仓库实际代码对照能更清晰地理解这套机制落在何处。事件一侧Coolify 将领域事件集中在 app/Events事件类通常组合Dispatchable有的还实现ShouldBroadcast例如 ServerReachabilityChangedclass ServerReachabilityChanged { use Dispatchable; public function __construct( public readonly Server $server ) { $this-server-isReachableChanged(); } }分发点遍布代码库例如 Server.php 内部、ServerConnectionCheckJob.php 与 Show.php 等都通过ServerReachabilityChanged::dispatch($server)发出事件ServiceStatusChanged::dispatch(...)则出现在 StopApplication、StopDatabase、StopService 等多个 Action 的收尾阶段。Action 内部发出事件、由监听器接手后续动作正是 Action 事件组合的典型形态。监听器一侧仓库里现有监听器多为传统监听器类例如 CloudflareTunnelChangedNotification 以handle(CloudflareTunnelChanged $event)处理 Cloudflare 隧道变更轮询容器健康状态、更新server的 IP 与设置并进一步分发CloudflareTunnelConfiguredProxyStatusChangedNotification 则在ProxyStatusChanged后同步代理状态并派发版本检查任务。对照参考文档的思路如果希望把这些监听器动作沉淀为可复用、可 fake 的用例就可以把它们改造成Action-as-Listener把handle(CloudflareTunnelChanged $event)的内部逻辑拆成handle(Server $server)业务层asListener(CloudflareTunnelChanged $event)从事件中取出server_id、ssh_domain并查询 Server 后转发从而获得 Action 独有的编排与测试能力。注册位置映射注册在 app/Providers/EventServiceProvider.php。该文件继承了 Laravel 的EventServiceProvider其$listen目前用于注册第三方SocialiteWasCalled相关的社会化登录扩展shouldDiscoverEvents()返回true表明 Laravel 会自动发现app/Listeners下的监听器。⚠️ 自动发现有一个重要前提它扫描的是约定目录如app/Listeners下的类。而 Action 通常放在app/Actions/...如App\Actions\Server、App\Actions\Database不在自动发现范围内。因此把 Action 当作监听器时必须像上文那样在$listen中显式映射事件与 Action或显式采用其他注册途径——这正好呼应参考文档显式映射必不可少的告诫。五、Checklist接入前的自检清单参考文档在收尾给出了接入清单落地时可逐项核对事件到监听器的映射已注册在EventServiceProvider的$listen中或在项目等效注册位置声明SomeEvent::class [SomeAction::class]若 Action 不在app/Listeners中自动发现不会覆盖它必须显式注册。监听器方法签名与事件契约匹配asListener(SomeEvent $event)的类型提示与事件类一致从事件中取出的字段真实存在、类型正确例如$event-server、$event-data。监听器测试覆盖分发 Action 交互使用Event::fake()Event::assertDispatched(...)验证事件分发必要时叠加 Action 假件验证 Action 是否被正确调用、参数是否按预期。六、常见陷阱Common Pitfalls参考文档点名了两个高频错误值得在编码时警惕1. 以为监听器会自动注册实则必须显式映射use AsAction只能赋予 Action 作为监听器被调用时所需的适配能力并不能让事件自动绑定到该 Action。缺少EventServiceProvider::$listen中的显式声明事件被 dispatch 后 Action 永远不会被触发。如前所述Action 位于app/Actions时尤其容易踩坑因为它绕开了 Laravel 的监听器自动发现约定。2. 在asListener(...)中重复实现业务逻辑asListener的角色是适配器从事件中解包数据、转交调用而非业务承载者。把司机筛选、报价计算等逻辑塞进asListener会导致同一逻辑在对象直调队列任务监听器等多个入口间被复制违背 Action 模式的初衷。正确姿势始终是asListener只负责$this-handle($event-x, $event-y);这类转发。七、延伸与项目内其他入口、测试约定协同asListener并非孤立存在它与 Laravel Actions 的整体工作流协同多入口复用同一业务SKILL 中强调先实现handle仅在需要时补充入口方法。Coolify 的 StartService 即为范例——handle(Service $service, ...)承载完整启动编排configureJob(JobDecorator $job)仅补充队列细节同理若某用例还需响应事件追加asListener即可业务零改动。两阶段测试策略第一层直接测handle(...)的业务正确性第二层测入口接线如asListener的映射与参数转发。前者保证业务不受入口干扰后者保证事件链路不失效。同一技能族下的横向参考本仓库.cursor/skills/laravel-actions/下还有references/command.md命令入口、references/job.md任务入口、references/controller.md控制器入口、references/object.md对象入口以及references/testing-fakes.md假件与断言、references/troubleshooting.md排查设计多入口 Action 时可横向对照SKILL.md则提供了从确认安装composer show lorisleiva/laravel-actions→ 先写handle→ 按需补入口 → 分层测试的完整工作流。结语asListener让 Laravel Actions 从HTTP/队列/CLI 三件套扩展到了事件驱动领域业务留在handle事件解包交给asListener绑定关系在EventServiceProvider中显式声明验证交给Event::fake()与 Action 假件。对于大量以 Action 组织远程命令与状态同步的 Coolify 而言这一入口是把零散监听器逻辑收敛为可复用、可测试用例的理想通道——只需遵守显式注册、签名匹配、逻辑只写一份三条纪律即可平滑落地。【免费下载链接】coolifyAn open-source, self-hostable PaaS alternative to Vercel, Heroku Netlify that lets you easily deploy static sites, databases, full-stack applications and 280 one-click services on your own servers.项目地址: https://gitcode.com/GitHub_Trending/co/coolify创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表