oikynブログ

エンジニアの技術ブログ。主にWEB、iOS、サービス、ツールなどなど。

Phalcon 1.2.4 (PHP Framwork)::APIスケルトン その2

Phalcon

前回の記事に記述したディレクトリ構成に、
interfacesというディレクトリを追加してみました。

├─collections
│      UserCollection.php
│
├─config
│      config.php
│      loader.php
│      services.php
│
├─controllers
│      ControllerBase.php
│      UserController.php
│
├─interfaces
│  ├─request
│  │  ├─fields
│  │  │      CommonFields.php
│  │  │      UserFields.php
│  │  │
│  │  └─validation
│  │      │  UserValidation.php
│  │      │  ValidationBase.php
│  │      │
│  │      └─custom
│  │              Custom.php
│  │              Date.php
│  │              Type.php
│  │
│  └─response
│      │  ResponseBase.php
│      │  UserResponse.php
│      │
│      └─fields
│              UserFields.php
│
├─models
└─views

追加したinterfacesディレクトリには、
名前の通り、主に、request、responseに関するクラスを
入れました。

サンプルソース

controllers/UserController.php
require __DIR__ . '/../interfaces/request/validation/UserValidation.php';
require __DIR__ . '/../interfaces/response/UserResponse.php';

class UserController extends ControllerBase {

    public function getUser() {
        $req = $this->input();

        //バリデーション処理
        $uv = new UserValidation();
        $valid = $uv->getUserValidation($req);

        if ($valid->count()) {
            //Error
            $msg = $valid[0]->getMessage();
            $this->output(400, UserResponse::errorResponse(400, $msg));
            return;
        }

        //DB操作

        //レスポンス
        $this->output(200, UserResponse::getUserResponse({DB操作した結果の配列}));
    }

}

コントローラーでは、基本的に全て共通して、

リクエストを取得
↓
バリデーションチェック
↓
エラーの場合は、エラーレスポンスを返す
↓
エラーがない場合は、DB操作を何かする
↓
レスポンスデータを作成し、JSONを返す

といった感じですかね。

バリデーションチェックでは、
nullチェックや、型チェック、値チェック、長さチェックなど
基本的なことをやります。

また、リクエストフィールドに対するバリデーションチェックは、
APIの種類に関係なく、基本は同じはずだと思います。
(nullがOKの有無はAPIの種類によって異なる場合はあるかと思います。)

なので、APIで扱う全てのリクエストフィールド情報は、
interfaces/request/fields/CommonFields.php
に記述するようにしました。

内容としては、
フィールド名、フィールドに対して使用するバリデーションインスタンス
となります。

サンプルソース

interfaces/request/fields/CommonFields.php
<?php

use Phalcon\Validation\Validator\PresenceOf,
    Phalcon\Validation\Validator\InclusionIn,
    Phalcon\Validation\Validator\Email,
    Phalcon\Validation\Validator\Between,
    Phalcon\Validation\Validator\StringLength;

class CommonFields {

    //Request Fields
    protected $_fields;

    public function __construct() {
        $this->_fields = array(
            'sex' => array(
                'default' => array(
                    new PresenceOf(array(
                        'cancelOnFail' => TRUE,
                            )),
                    new InclusionIn(array(
                        'domain' => array('male', 'female'),
                        'cancelOnFail' => TRUE
                            )),
                ),
                'custom' => array(
                    new Type(array(
                        'type' => 'string'
                            )),
                ),
            ),
            'birthday' => array(
                'default' => array(
                    new PresenceOf(array(
                        'cancelOnFail' => TRUE,
                            )),
                ),
                'custom' => array(
                    new Type(array(
                        'type' => 'integer'
                            )),
                    new Date(array(
                        'format' => 'Ymd'
                            )),
                ),
            ),
            ~省略~
        );
    }

    public function getFields() {
        return $this->_fields;
    }

}

バリデーションの部分が
defaultとcustomに分かれているのは、
Phalconで用意されているバリデーションクラスと、
自前で用意したバリデーションクラスを区別するためです。

上記のクラスでは、APIの全てで扱うフィールドを設定したので、
interfaces/request/fields/UserFields.php
では、各APIで扱うフィールドを記述するようにしました。

サンプルソース

interfaces/request/fields/UserFields.php
namespace Interfaces\Request\Fields {

    class UserFields {
        static public function getUserFields() {
            return array(
                array('sex', TRUE),
                array('birthday', TRUE),
                ~省略~
            );
        }
    }
}

TRUEの部分は、NOT NULLのフラグとしています。
ここをFALSEにすると、バリデーションチェックで、
nullチェックは行わないようにします。

バリデーションチェックして、OKだったら、
何かDB操作して、レスポンスを返さなければいけません。

リクエストと同様にして、
APIごとにレスポンスのフィールドも設定するようにします。

サンプルソース

interfaces/response/fields/UserFields.php
<?php

namespace Interfaces\Response\Fields {

    class UserFields {
        static public function getUserFields() {
            return array(
                'sex',
                'birthday',
            );
        }
    }
}

DBから得られた結果から、上記で設定したフィールドをもとに
必要なものだけを取得して、レスポンスを作成し、クライアントに返します。

ここまで、ソースを抜粋しながら、簡単な説明を記載してきました。
DB操作以外の部分は、
API実装前に存在している仕様書から全て設定できる範囲なので、
実装の半分くらい?は簡単にできるのではないかなと感じてます。