コンテンツにスキップ

インターフェース層@クリーンアーキテクチャ

はじめに

本サイトにつきまして、以下をご認識のほど宜しくお願いいたします。


01. インターフェース層 (プレゼンテーション層、デリバリー層)

インターフェース層とは

リクエストを受信し、構造を変換してユースケース層に渡す。


02. コントローラー

コントローラーとは

入力/出力の処理時で、責務を以下の様に分類できる。

コントローラーの責務をデザインパターンに切り分けても良い。

入力時/出力時 責務 補足
入力 インフラストラクチャ層のWeb APIから入力される資格情報を照合し、認証する。 認証はインターフェース層あるいはユースケース層に実装する。<br>https://github.com/little-hands/ddd-q-and-a/issues/173
インフラストラクチャ層のWeb APIから入力されるパラメーターをAPI仕様 (必須、書式など) と照らし合わせ、バリデーションを実行する。 データの値がAPI仕様と比較して正しいか否かを検証することに止まり、データの値が正しいか否かの検証は、ユースケース層やドメイン層に実装する。
インフラストラクチャ層のWeb APIから入力されるパラメーターをリクエストモデルに変換し、ユースケース層のインターラクターに入力する。 リクエストモデル作成処理で、ドメイン層への依存が必要になる。リクエストモデル作成処理を切り分け、ユースケース層に配置すると、コントローラーがドメイン層に依存することを防げる。
出力 ユースケース層のインターラクターから出力されるレスポンスモデルを、JSON型データとしてフロントエンドに返信する。 バックエンドをAPIとして使用する場合、プレゼンターは不要である。
ユースケース層のインターラクターから出力されるプレゼンターをビューモデルに変換し、バックエンドのテンプレートエンジンに出力する。 バックエンドでテンプレートエンジンを使用してHTMLを作成する場合、プレゼンターが必要である。

認証

通常のネイティブ認証とSSOが共存する場合、ユーザーはどちらかしか選べないようにフラグを管理し、競合しないようにする。

もし通常のネイティブ認証を選んだユーザーの場合、メールアドレスやパスワードをDBに保存する。

SSOの場合を選んだユーザーの場合、IDプロバイダーから取得したユーザーの最低限の情報 (メールアドレス) だけをDBに保存する。


03. プレゼンター

プレゼンターとは

バックエンドがテンプレートエンジンを持つフレームワークの時に、バックエンドからフロントエンドのロジックを分離するために使用する。

一方で、フロントエンド領域とバックエンド領域を完全に分離する場合がある。例えば、バックエンドがJSON型データを返信するAPIとして動作する場合や、フロントエンドにテンプレートエンジンを組み込む場合は、プレゼンターを使用しない。

補足として、アウトプットバウンダリはプレゼンターのインターフェースのため、プレゼンターを使用しなければ、アウトプットバウンダリも使用しない。


04. バリデーションパターン

バリデーションパターンとは

デザインパターンの一種。

インターフェース層のバリデーションでは、データの必須や書式を検証する。

APIにおける入力値のバリデーション

*実装例*

日時データのフォーマットを検証する。

<?php

namespace App\Interface\Foo\Validators;

// Validationのパッケージ
use Respect\Validation\Validator;

class FormatValidator
{
    /**
     * 日時データのフォーマットを検証する
     */
    public function validateFormat($dateTime)
    {
        if (empty($dateTime)) {
            return false;
        }

        if (!Validator::date(\DateTime::ATOM)->validate($dateTime)) {
            return false;
        }

        return true;
    }
}

UIおける入力値のバリデーション

記入中...

クエリストリングにバリデーションは必要かどうか

受信したURLクエリストリングの形式が誤っていた場合、デフォルト値で処理するように実装するとよい。

<?php

namespace App\Interface\Foo\Validators;

// Validationのパッケージ
use Respect\Validation\Validator;

class UrlValidator
{

    /**
     * URLクエリストリングの値を検証し、不正ならデフォルト値を返す。
     */
    public function validateFormat($value, $validator)
    {
        // 例:ページングやソートのURLクエリストリングを想定する。
        // - page: 1始まり
        // - limit: 1〜100
        // - sort: created_at の昇順/降順
        $defaultValues = [
            'page'  => 1,
            'limit' => 20,
            'sort'  => 'created_at_desc',
        ];

        // クエリストリングが不正ならデフォルト値を使用する
        if (!$validator->validate($value)) {
            return $defaultValue;
        }

        return $value;
    }
}