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

焦点を絞ったドメイン アプリケーションの作成。 Symfony のアプローチ (パート 1)

Patricia Arquette
Patricia Arquetteオリジナル
2024-11-03 10:52:29665ブラウズ

導入

これは、symfony アプリケーションをどのように整理するか、そして可能な限りドメイン指向のコードを書く方法を説明するために作成することにしたシリーズの最初の投稿です。
以下に、シリーズのすべてのパートで使用するフロー図を示します。各投稿では、図の具体的な部分に焦点を当て、関係するプロセスを分析し、どの部分が私たちのドメインに属するのか、また外部レイヤーを使用して他の部分から切り離す方法を検出しようとします。

Creating focused domain applications. A Symfony approach (Part 1)

データ処理の内訳

この最初のパートでは、データの抽出と検証のプロセスに焦点を当てます。データ抽出プロセスでは、リクエスト データが JSON 形式で提供されると想定します。

データの抽出

リクエスト データが JSON リクエスト ペイロード内に含まれることがわかっているという事実に基づくと、リクエスト ペイロードの抽出 (この場合、抽出とは JSON ペイロードから配列を取得することを意味します) は、php の json_decode 関数を使用するのと同じくらい簡単です。

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request,): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        // validate data
    }
}

データの検証

データを検証するには、次の 3 つの要素が必要です。

  • 検証ルールを定義するための 1 つ。
  • 要求されたデータを有効なオブジェクトに変換するためのもの。
  • 抽出されたデータをこれらのルールに基づいて検証するためのもの。

検証ルールの定義

最初の方法では、受信データを表す DTO (データ転送オブジェクト) を作成し、Symfony 検証制約属性を使用してこのデータを検証する方法を指定します。

readonly class UserInputDTO {
    public function __construct(
        #[NotBlank(message: 'Email cannot be empty')]
        #[Email(message: 'Email must be a valid email')]
        public string $email,
        #[NotBlank(message: 'First name cannot be empty')]
        public string $firstname,
        #[NotBlank(message: 'Last name cannot be empty')]
        public string $lastname,
        #[NotBlank(message: 'Date of birth name cannot be empty')]
        #[Date(message: 'Date of birth must be a valid date')]
        public string $dob
    ){}
}

ご覧のとおり、最近作成した DTO 内で入力データ検証ルールを定義しました。これらのルールは次のとおりです:

  • 電子メール: 空にすることはできません。有効な電子メールである必要があります
  • : 空にすることはできません
  • : 空にすることはできません
  • dob (生年月日): 空にすることはできず、有効な日付である必要があります。

リクエストデータを DTO に非正規化する

2 つ目では、Symfony ノーマライザー コンポーネントを使用します。これにより、リクエストの受信データを DTO にマッピングできます。

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request, SerializerInterface $serializer): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        $userInputDTO = $serializer->denormalize($requestData, UserInputDTO::class);
    }
}

上に示したように、denormalize メソッドが処理を実行し、1 行のコードで DTO に受信データが入力されます。

DTO の検証

最後に、データを検証するために、最近非正規化された DTO (受信データを運ぶ) のインスタンスを受け取り、DTO ルールに従ってデータを検証する Symfony バリデーター サービスに依存します。

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request,): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        // validate data
    }
}

ドメインの特定

これまで、抽出データの検証のプロセスを 4 つの部分に分割してきました。

  • JSON リクエスト ペイロードから配列を抽出します。
  • 受信データとその検証ルールを表す DTO を作成します。
  • 配列を検証ルールを含む DTO に非正規化します。
  • DTO を検証します。

ここでの質問は、次のどの部分が私たちのドメインに属しているのかということです。
質問に答えるために、関連するプロセスを分析してみましょう:

1.- データの抽出: この部分では、「json_decode」関数のみを使用して、受信データを json から配列に変換します。ビジネス ロジックは追加されないため、これはドメインに属しません。

2.- DTO: DTO には、入力データに関連付けられたプロパティとその検証方法が含まれます。これは、DTO にビジネス ルール (検証ルール) が含まれているため、DTO がドメインに属することを意味します。

3.- データの非正規化: この部分は単にインフラストラクチャ サービス (フレームワーク コンポーネント) を使用して、データをオブジェクトに非正規化します。これにはビジネス ルールが含まれていないため、これは私たちのドメインに属しません。

4.- データの検証: データの非正規化 プロセスと同じ方法で、データ検証プロセスでもインフラストラクチャ サービス (フレームワーク コンポーネント) を使用して受信データを検証します。 。これにはビジネス ルールが含まれていません。ビジネス ルールは DTO で定義されているため、ドメインの一部にもなりません。

最後のポイントを分析した後、DTO のみがドメインの一部になると結論付けることができます。では、コードの残りの部分をどうすればよいでしょうか?

アプリケーションサービスの作成

個人的には、この種のプロセス (データの抽出、非正規化、検証) をアプリケーション層またはサービス層に組み込むのが好きです。なぜ?、アプリケーション層を紹介しましょう。

アプリケーション層

つまり、アプリケーション層はオーケストレーションと調整を担当し、ビジネス ロジックはドメイン層に任せます。さらに、ドメイン層と、プレゼンテーション層 (UI) やインフラストラクチャ層などの外部層との間の仲介者として機能します。
上記の定義から始めて、抽出非正規化、および 検証 プロセスをアプリケーション層のサービスに含めることができます。次の理由からです。

  • 受信データ処理を調整します。
  • インフラストラクチャ サービス (PHP JSON 関数、Symfony 正規化コンポーネント、Symfony 検証コンポーネント) を使用して受信データを処理します。
  • DTO を検証インフラストラクチャ サービスに渡すことで、ドメイン ルールを適用します。

完璧です。このプロセスを管理するアプリケーション サービスを作成します。どうやってやろうか?責任をどのように管理するのでしょうか?

責任の分析

単一責任原則 (SRP) は、各クラスがアプリケーションの動作の 1 つの部分のみに対して責任を負うべきであると規定しています。クラスに複数の責任がある場合、理解、維持、変更がより困難になります。

これは私たちにどのような影響を与えますか?それを分析してみましょう。
これまでのところ、アプリケーション サービスは受信データを抽出、非正規化、検証する必要があることがわかっています。これを理解すると、次の責任を簡単に抽出できます:

  • データの抽出
  • データの非正規化
  • データを検証する

これらの責任を 3 つの異なるサービスに分割する必要がありますか?そうは思いません。説明しましょう。

これまで見てきたように、各責任はインフラストラクチャ機能またはコンポーネントによって管理されます。

  • 責任の抽出: PHP json_decode 関数
  • データ責任の非正規化: Symfony ノーマライザー コンポーネント
  • データ責任の検証: Symfony 検証コンポーネント

アプリケーション サービスはこれらの責任をインフラストラクチャ サービスに委任できるため、より抽象的な責任 (データの処理) を作成し、それをアプリケーション サービスに割り当てることができます。

class ApiController extends AbstractController
{
    #[Route('/api/entity', name: 'api_v1_post_entity', methods: ['POST'])]
    public function saveAction(Request $request,): JsonResponse
    {
        $requestData = json_decode($request->getContent(), true);
        // validate data
    }
}

上に示したように、DataProcessor アプリケーション サービスは、json_decode 関数と Symfony のノーマライザーおよびバリデータ サービスを使用して入力リクエストを処理し、新しく検証された DTO を返します。したがって、DataProcessor サービスは次のようになります。

  • 入力データの処理に関連するすべてのタスクを調整します。
  • ドメイン ビジネス ルール (DTO) を使用して外部 (インフラストラクチャ サービス) と通信します。

お気づきかと思いますが、検証プロセスでエラーが見つかった場合、DataProcessor サービスは Symfony ValidationException をスローします。このシリーズの次回の投稿では、ビジネス ルールを適用してエラーを構造化し、最終的にクライアントに提示する方法を学びます。

DataProcessor サービスを削除し、MapRequestPayload をサービス アプリケーション層として使用して、データの抽出、非正規化、検証を行うことができることはわかっていますが、この記事の文脈を考えると、より便利だと思いました。このように書いてください。

結論

この最初の記事では、フロー図からのデータの抽出と検証のプロセスに焦点を当てました。このプロセスに含まれるタスクをリストし、どの部分がドメインに属しているかを検出する方法を学びました。
どの部分がドメインに属しているかを把握して、ドメインがルールを定め、データの抽出と検証のプロセスを調整するインフラストラクチャ サービスを接続するアプリケーション層サービスを作成しました。
次の記事では、例外を管理するためのビジネス ルールを定義する方法を検討し、入力 DTO を永続的なエンティティに変換する役割を担うドメイン サービスも作成します。

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

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