pitch/symfony-adr 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

pitch/symfony-adr

Composer 安装命令:

composer require pitch/symfony-adr

包简介

This bundle makes it easier to follow ADR pattern while writing a Symfony application

README 文档

README

This bundle makes it easier to follow ADR pattern while writing a Symfony application.

Usage

Turn controller into action

Decouple responder logic from action logic by moving it out of the controller. Just return the payload!

If a controller returns anything but a Response object, Symfony dispatches a kernel.view event.

Now instead of registering a bunch of event listeners to be iterated through, implement ResponseHandlerInterface.

namespace App\Responder;

use Pitch\AdrBundle\Responder\ResponseHandlerInterface;
use Pitch\AdrBundle\Responder\ResponsePayloadEvent;
use Symfony\Component\HttpFoundation\Response;

use App\Entity\MyPayload;

class MyPayloadHandler implements ResponseHandlerInterface
{
    public function getSupportedPayloadTypes(): array
    {
        return [
            MyPayload::class,
        ];
    }

    public function handleResponsePayload(
        ResponsePayloadEvent $payloadEvent
    ): void {
        $response = new Response();

        // prepare the response
        if ($payloadEvent->request->getAttribute('_foo') === 'bar') {
            // adjust the response according to the request
        }

        $payloadEvent->payload = $response;
    }
}

If your handler class is available as a service according to your config/services.yaml, it will be discovered and used whenever a MyPayload object is returned by a controller.

With default config just put the class into src/Responder/MyPayloadHandler.php and you are done.

Your response handler can report its priority in getSupportedTypes.

class MyPayloadHandler implements ResponseHandlerInterface
{
    public function getSupportedPayloadTypes(): array
    {
        return [
            MyPayload::class => 123,
            MyOtherPayload:class => 456,
        ];
    }
    //...
}

Or you can overwrite the handled types and priorities for response handlers in your services.yml.

services:
  App\Responder\MyPayloadHandler:
    tags:
      - name: pitch_adr.responder
        for: [App\Entity\MyPayload]
        priority: 1000
      - name: pitch_adr.responder
        for: [App\Entity\MyOtherPayload]
        priority: 0

You can easily debug your responder config per console command.

$ php bin/console debug:responder MyPayload

Treat some exceptions as response payload

A robust domain will have strict constraints and throw exceptions whenever an unexpected or invalid condition occurs and for every exception falling through your controller/action Symfony dispatches a kernel.exception event.

You can reserve this event for truly unexpected behavior without repeating similar try-catch-blocks across your controllers.

Define which exceptions should be catched for all controllers and be treated as response payload:

pitch_adr:
    graceful:
        - { value: RuntimeException, not: [BadRuntime, OtherBadRuntime] }
        - Foo
        - { not: GloballyBadException }
        - { value: Bar, not: BadBar }

If Doctrine Annotations is installed, you can define extra rules for your controller methods per annotation:

namespace App\Controller;

use Pitch\AdrBundle\Configuration\Graceful;

class MyController
{
    /**
     * @Graceful(not=LocallyBadException::class)
     * @Graceful(LocallyGoodException::class, not={ButNotThisOne::class, OrThatOne::class})
     */
    public function __invoke(
        Request $request
    ) {
        /// ...
    }
}

With PHP8 you can define extra rules per Attribute:

namespace App\Controller;

use Pitch\AdrBundle\Configuration\Graceful;

class MyController
{
    #[Graceful(not: LocallyBadException::class)]
    #[Graceful(LocallyGoodException::class, not: [ButNotThisOne::class, OrThatOne::class])]
    public function __invoke(
        Request $request
    ) {
        /// ...
    }
}

Rules are applied in the order of appearance, method rules after global rules.

Now you can just create a App\Responder\MyGoodRuntimeExceptionHandler as described above.

Default response handlers

The bundle automatically adds some response handlers for basic types with negative priority so that they will be called if none of your response handlers stops propagation earlier. If you don't want the default handlers to be added, you can modify this behavior per bundle configuration.

pitch_adr:
    defaultResponseHandlers: false # defaults to true

Prioritised response handlers

If consecutive response handlers (in the order of config priority) implement PrioritisedResponseHandlerInterface, that block of handlers will be reordered on runtime according the priority they report for the specific request per getResponseHandlerPriority.

Given the following response handlers are configured to handle a `SomePayloadType`:

900: HandlerA
600: PrioritisedHandler1 with getResponseHandlerPriority(): 1
500: PrioritisedHandler2 with getResponseHandlerPriority(): 2
400: PrioritisedHandler3 with getResponseHandlerPriority(): 0
100: HandlerB

these will be executed in the following order:

HandlerA
PrioritisedHandler2
PrioritisedHandler1
PrioritisedHandler3
HandlerB

Negotiating content type in response handlers

See JsonResponder on how to implement your own prioritised response handlers that handle a payload according to the Accept header on the request.

You can set a default content type for requests that don't include an Accept header. This can be done per container parameter or as controller annotation.

parameters:
    pitch_adr.defaultContentType: 'application/json'
use Pitch\AdrBundle\Configuration\DefaultContentType;

class MyController
{
    #[DefaultContentType('application/json')]
    public function __invoke()
    {
        // ...
    }
}

统计信息

  • 总下载量: 270
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 3
  • 点击次数: 0
  • 依赖项目数: 1
  • 推荐数: 1

GitHub 信息

  • Stars: 2
  • Watchers: 1
  • Forks: 0
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2021-05-05

承接程序开发

PHP开发

VUE

Vue开发

前端开发

小程序开发

公众号开发

系统定制

数据库设计

云部署

网站建设

安全加固