BEAR.Sunday開発初期に考えてたことや出来事をいくつか紹介したいと思います。
BEAR.Saturday
その頃は単にBEARと呼んでいたBEAR.SaturdayというPHP5.2の時代に作ったフレームワークを、PHP5.3に書き直そし次のバージョンにしようとしたのが制作の最初の動機です。
BEAR.Saturdayは同じアプリケーションで携帯とPC、各キャリアで表示が出し分けられるように作られていました。開発者は各キャリアの文字エンコード(SJIS,UTF8)や携帯の文字コードを意識する事なく開発する事が出来ました。
開発は順調でしたが、ほぼ完成が見えた時点で開発を中止する事にしました。確かにコードの品質は上がり、スタイルも洗練されたように思いました。しかし表面的なものが良くなったとしても、本質的な価値向上がないものを後方互換性を破壊してまで提供する事に疑問を感じました。
API-Centric
携帯電話の時代が終わりつつある中「API中心のアプリケーション」という着想を得ます。アプリケーションが扱う意味の情報や操作を、リソースというHTTPに習った強い境界の中に閉じ込め、ステートレスリクエスト、アドレス可能なURI、統一インターフェイス、ステータスコード、属性と言ったRESTの設計原則を取り入れる事にしました。
以下はチュートリアルのコードです。
class Weekday extends ResourceObject
{
public function onGet(int $year, int $month, int $day) : ResourceObject
{
$weekday = \DateTime::createFromFormat('Y-m-d', "$year-$month-$day")->format('D');
$this->body = [
'weekday' => $weekday
];
return $this;
}
}
このリソースのクラスメソッドは、HTTP(REST)の世界とPHP(OOP)の世界の橋渡しとなる境界です。
クラス名がURI(/weekday
)にマップされ、リクエストに必要な引数はメソッドシグネチャーに$year
、$month
、 $day
と表されます。メソッドの中のコードを読む事なく、ドキュメントを参照する事なく、リクエストに必要な引数が表されるべきで、このようにクラスやメソッドシグネチャーそのものがリソースのスペックになればいいと考えました。1
ルーティング
BEAR.Sunday + Swooleの記事でも紹介したPHP作者のPHPフレームワーク批判に以下のものがあります。
Duplicating the Web Server Functionality
フレームワークはwebサーバーの機能(ルーター)を複製している
本来phpはpublic
フォルダに置かれた場所に置いてURIが決定されますが、BEAR.Sundayでも基本はクラス名(クラスファイルの位置)でURIが決定します。Webルーターの場合はルーターファイルを用意する必要もありません。2
同じように最小限の構成ではリソースのファイルを1つ設置しただけで(全体構造を理解する必要なく)APIができるのが理想と考えました。実際に上記の日付から曜日をレスポンスとして返す/weekday
リソースはファイル1つ設置するだけでAPIとして機能します。
値と表現の分離
「リソースはメソッドで与えられた引数に基づいて自らの状態を決定し、その表現については興味を持たない。」
状態に関心を持つビューのコンポーネントがリソースオブジェクトにインジェクトされ、そのリソースオブジェクトが(文字通り)文字列評価された時に文字列(表現)になれば良いと考えました。3
表現を返してしまうやり方に比べ、メソッドは値だけを返しているのでテストは容易です。JSON表現、HTML表現といった表現の種別を実行コンテキストを変えるだけで(ソースコードや設定ファイルを変更することなく変えることができます。
この部分の設計はBEAR.SundayのリソースクラスでRESTから着想を得てない珍しい部分ですが後になるほど強力に機能した部分でもあります。
終わりに
本当に少しだけ紹介しましたが、どのように新しいフレームワークの着想を得て形にしていくか、違う形でしっかり紹介できる機会が持てればと思います。ソフトウエア"開発"に興味がある人に有用なお話ができたら良いと思います。
@kumamidori さん、今年もカレンダーの設置ありがとうございました。@jingu君も、@77webさんも記事をありがとうございました。小さなカレンダーでしたけど、それぞれの問題の取り組みが記事になって良かったと思います。
今年も残りわずか。良いお年を。
Merry Christmas and HaPHPy new BEAR 2019 !!
-
後にJsonスキーマが導入されレスポンスの詳細についてもメソッドの外で定義され、コードから入出力のドキュメントの自動生成とバリデーションができるようになりました。 ↩
-
一般的なMVCフレームワークは、ルーターでURIとクラスのマップを行い、フロントコントローラーがディスパッチャーとしてページコントローラーを呼び出し、ほぼ全てのHTTP入力値を
Request
オブジェクトとして渡されます。 ↩ -
一方、MVCフレームワークの構造上の明らかな問題点は、C、すなわちコントローラーの責任の多さです。HTTPリクエスト全てが入ったオブジェクトを受け取り、全てのモデルとデータのやり取りが可能でその結果表現にも責任を持ちます。単一責任原則からも離脱しています。 ↩