ホームページ  >  記事  >  バックエンド開発  >  焦点を絞ったドメイン アプリケーションの作成。 Symfony のアプローチ (検証エラーの管理)

焦点を絞ったドメイン アプリケーションの作成。 Symfony のアプローチ (検証エラーの管理)

Susan Sarandon
Susan Sarandonオリジナル
2024-11-10 17:23:02394ブラウズ

Creating focused domain applications. A Symfony approach (Managing validation errors)

導入

前回の投稿では、シリアライザーとバリデーターの symfony コンポーネントが、アプリケーションで一般的なタスクを実行するのに役立つツールを提供するインフラストラクチャー・サービスとしてどのように機能するかを分析しました。また、ビジネス ルールが含まれているため、UserInputDTO クラスがドメインに属する要素である理由と、データ フローの抽出と検証を実行するアプリケーション層サービスの作成方法についても学びました。

この 2 番目のパートでは、検証エラーを管理する方法を説明し、最初のパートと同様に、ドメインに属する部分を特定します。

検証エラー

検証エラーは、検証制約を使用して確立されたルールに従って UserInputDTO を検証した後、Symfony バリデーターコンポーネントによって返されます。

public function processData(string $content, string $dtoClass): object
{
     $requestData = json_decode($content, true);
     $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class);
     $errors = $validator->validate($userInputDTO);
     if(count($errors) > 0) {
         throw new ValidationFailedException($errors);
     }

     return $userInputDTO
}

上記のコードでわかるように、検証メソッドでエラーが検出された場合、ValidationException タイプの例外がスローされます。ここから、ユーザーにエラーをどのように表示するか (ドメイン/ビジネス ルール)、エラーがユーザーに正しく届くようにどのツールに依存するか (インフラストラクチャとアプリケーション) を決定する必要があります。

検証エラーの捕捉を一元化する

最初に考慮しなければならないのは、検証エラーが発生するたびにそれを捕捉したいということです。これを達成するには、インフラストラクチャ層に依存します。
Symfony カーネルには、特別なイベントをリッスンするための一連の組み込みカーネル イベントが付属しています。このイベントの 1 つは、例外がスローされたときにトリガーされるカーネル例外イベントです。 ValidationException エラーを捕捉するためにこれを使用してみましょう。

class KernelSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::EXCEPTION => 'onException'
        ];
    }

    public function onException(ExceptionEvent $event): void
    {
        $exception = $event->getThrowable();
        if($exception instanceof ValidationFailedException){
            // Business rules to build the errors
        }
    }
}

上記のコードでわかるように、KernelSubscriberKernelException イベントをリッスンし続け、キャッチされた例外が ValidationFailedException クラス. ここからは、
onException メソッドが検証エラーであることを検出したときに実行されるロジックを定義する必要があります。

エラー配列を構築するためのドメイン サービスの作成

私たちはエラーをどのように構成するかを決定する責任があるため (ビジネス ルールを定義するのは私たちです)、ロジックを実行するサービスは私たちのドメインに属します。コードを書いてみましょう


class ValidationErrorsBuilder {

    public function buildErrors(ValidationFailedException $exception): array
    {
        $errors = [];
        foreach ($exception->getViolations() as $violation) {
            $errors[$violation->getPropertyPath()] = $violation->getMessage();
        }

        return $errors;
    }
}

ValidationErrorsBuilder コードは非常に単純です。違反エラーをループし、キーがエラーを生成したプロパティ、値がエラー メッセージである連想配列を作成します。

ValidationErrorsBuilder の使用

今度は、ValidationErrorsBuilder ドメイン サービスを使用します。 KernelSubscriber onException メソッドで使用しています。

public function processData(string $content, string $dtoClass): object
{
     $requestData = json_decode($content, true);
     $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class);
     $errors = $validator->validate($userInputDTO);
     if(count($errors) > 0) {
         throw new ValidationFailedException($errors);
     }

     return $userInputDTO
}

ご覧のとおり、例外が ValidationFailedException であることがわかった後、ドメイン サービスを使用して検証エラー配列を取得します。
それでは、次のコードを見てみましょう:

class KernelSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::EXCEPTION => 'onException'
        ];
    }

    public function onException(ExceptionEvent $event): void
    {
        $exception = $event->getThrowable();
        if($exception instanceof ValidationFailedException){
            // Business rules to build the errors
        }
    }
}

エラー配列を保持する Symfony JsonResponse を新しい応答として設定し、返される HTTP コードが 400 Bad Request になることを指定する新しい行を追加しました。
応答 HTTP コードを指定するには、Symfony 応答 HTTP_BAD_REQUEST 定数を利用してきました。ドメイン中心の環境で作業しているため、カスタム ドメイン クラス (例: php enum) を作成することもできますが、標準の HTTP コードを処理するだけでよく、特にカスタマイズする必要がないため、 Symfony HTTP コードですが、これによりフレームワークにもう少し依存することになります。

そしてアプリケーション層は?

これまでアプリケーション層については話してきませんでした。記事の冒頭で、Symfony フレームワークには、私たちが使用したカーネル例外イベントなどの便利な組み込みイベントが付属していると述べました。さらに、symfony フレームワークは、カスタム イベント サブスクライバーを作成し、必要なイベントをリッスンできる EventSubscriberInterface も提供します。
この情報から、symfony はカーネル例外イベントと EventSubscriberInterface を提供しますが、どのイベントをリッスンするかを指定するサブスクライバーを作成するにはインターフェースを使用する必要があると結論付けることができます。再開しましょう:

  • イベント サブスクライバーは、カーネル例外イベントをリッスンするように指定します。
  • イベント サブスクライバーは、例外が ValidationFailedException のインスタンスであるかどうかを確認します。
  • イベント サブスクライバーはドメイン サービスを使用してエラー配列を構築します。
  • イベント サブスクライバーは、エラーを保持する JsonResponse を作成し、それを最終応答として設定します。

これに聞き覚えはありますか?はい、イベント サブスクライバーは、例外がスローされた後の検証エラーの管理のオーケストレーションと調整を担当するため、イベント サブスクライバーはアプリケーション サービスとして機能すると言えます。
さらに一歩進めたい場合は、アプリケーション層サービスを作成し、それをサブスクライバで使用することもできます。

class ValidationErrorsBuilder {

    public function buildErrors(ValidationFailedException $exception): array
    {
        $errors = [];
        foreach ($exception->getViolations() as $violation) {
            $errors[$violation->getPropertyPath()] = $violation->getMessage();
        }

        return $errors;
    }
}
public function onException(ExceptionEvent $event): void
{
    $exception = $event->getThrowable();
    if($exception instanceof ValidationFailedException){
       $errors = $this->validationErrorsBuilder->buildErrors($exception);
    }
}

ValidationErrorsProcessor は、検証エラー応答管理を調整し、ValidationErrorsBuilder ドメイン サービスを使用するアプリケーション サービスとして機能します。

結論

このシリーズの 2 回目の記事では、検証エラー管理プロセスのどのコンポーネントがドメインに属しているか、使用したインフラストラクチャのどの要素か、カーネル サブスクライバがアプリケーション サービスとしてどのように動作できるかを特定しました。
次の記事では、エンティティをデータベースに永続化し、DTO を永続化可能なエンティティに変換するロジックを分離する方法を分析します。

以上が焦点を絞ったドメイン アプリケーションの作成。 Symfony のアプローチ (検証エラーの管理)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。