取り込まない
認証も検証もORMも抱え込みません。フレームワークは制約を与え、ライブラリは選べるまま。標準を選べる自由を残します。
Architecture
BEAR.Sundayは、Webの制約をアプリケーション内部の設計原則として扱います。Resource、DI、AOP、Contextが役割を分けるため、コードの意味が読みやすく、長期運用に耐える構造になります。
Design philosophy
BEAR.Sundayは、必要な技術を自分の中に取り込んで作り直しません。SQLはSQLのまま、検証はJSON Schemaのまま、リンクはHALのまま。重大な約束ごとほど、フレームワーク独自の発明ではなく、 公開された標準に従います。それぞれに仕事を任せるから、緊張ではなく調和が生まれます。
認証も検証もORMも抱え込みません。フレームワークは制約を与え、ライブラリは選べるまま。標準を選べる自由を残します。
JSON Schema、HAL、OpenAPI、SQL、PSRは、BEAR.Sundayの外でも通用する姿のまま使われます。投資がフレームワークに閉じ込められません。
検証はJSON Schema、リンクはHAL、API記述はOpenAPI。肝心な部分ほど独自構文を作らず、公開された標準で表します。だから文書化され、長く残り、他のツールやAIにもそのまま通じます。
SQLにオブジェクトのふりをさせません。それぞれが得意なことだけをする。無理な抽象がないから、継ぎ目に摩擦が出ません。
つなぐ場所に一つの仕事を与え、型で渡し、反対側を隠す。だから差し替えられ、長く保てる。 これは機能ではなく、設計哲学でありひとつの美学です。
アプリケーションの入口をページやコントローラーではなく、URIで識別できるリソースとして設計します。状態、リンク、表現の境界が揃うため、Web API、HTML、CLIで同じ意味を共有できます。
Google GuiceのコンセプトをPHPへ発展させたRay.Diで、型とQualifierをKeyにして依存関係を解決します。Moduleが束縛を宣言し、Injectorがオブジェクトグラフを生成します。
キャッシュ、トランザクション、ログ、認可などの横断的関心をInterceptorとして分離します。リソースクラスはアプリケーションの意味に集中できます。
prod-hal-api-app のようなcontext stringで環境・表現・アプリケーション種別を組み合わせます。環境分岐をアプリケーションコードに混ぜず、DI moduleで差分を表現します。
contextはオブジェクトグラフ生成時だけ使われ、生成後のオブジェクトは自分がどのcontextで作られたかを知りません。APP_DEBUGのような実行モード参照を構造から排除します。
フレームワークpackageもアプリケーションも、循環依存を避ける方向に構成されます。複数アプリケーションをHTTP境界ではなく、namespaceとDI bindingで統合し、他のPHPアプリケーションからもリソースとして呼び出せます。
Resource discipline
BEAR.Sundayのリソース志向は、URLで呼べる部品を作ることではありません。 アプリケーションの意味を置く場所を定め、そこから外側へ表現と接続を展開するための制約です。
機能の意味をResourceに置きます。表現、依存、遷移、キャッシュ、ドキュメントは、そこから外側へ展開されます。
Resource methodは外側のresponse objectを操作する場所ではありません。自分の状態を決め、返すのも自分自身です。
Resourceが持つのは値、状態、リンクです。HTML、JSON、CLIへの表現はrendererの関心で、Resourceは表現を知りません。
入力はmethod signature、型、属性、schemaで宣言されます。出力もbody、headers、links、schemaとして残り、暗黙の表示都合に埋もれません。
Ray.Di and Guice
Ray.Diの中心には、Google Guice由来の考え方があります。アプリケーションコードは依存を取りに行かず、 constructorで必要なものを宣言します。Moduleは「このKeyにはこのProvider」という束縛を定義し、 Injectorは依存の依存までたどって、実行前にobject graphを組み立てます。
だからBEAR.SundayのDIは、便利な自動配線ではありません。context、binding、scope、interceptorを object graphの構成として扱い、生成後のオブジェクトから構成情報への参照可能性を消します。
型とQualifier属性で依存を識別します。同じinterfaceでも、支払い用、ログ用、テスト用の実装を混同せずに扱えます。
束縛を集める構成単位です。機能、環境、表現ごとのModuleを組み合わせ、contextに応じたobject graphを作ります。
生成が複雑な依存、遅延生成、scopeの混在を扱います。利用側は生成方法を知らず、必要な依存だけを宣言します。
prototype、singletonなどのライフサイクルを束縛側で制御します。オブジェクト自身が自分の寿命を知る必要はありません。
AOP Allianceに近いMethodInterceptorで、トランザクション、認可、キャッシュを本体コードから分離します。
依存グラフからPHP factory codeを生成し、本番ではコンテナ初期化の負荷を抑えます。生成結果は追跡可能な構造になります。
Resource flow
MVCのように役割名で分けるのではなく、リソースを中心に状態とリンクをまとめます。 レンダリングや転送は外側へ分離されるため、リソースは「何であるか」を保ちます。
01
Request: app://self/profile?id=1
02
Resource: Profile::onGet(int $id)
03
Body: 状態を配列または値オブジェクトとして保持
04
Links: HALや属性で遷移可能性を宣言
05
Renderer: HTML、JSON、HAL、CLIへ表現を変換
Long-term structure
環境差分はcontext moduleで表現する
生成後のオブジェクトはcontextを知らない
表現形式はrendererで切り替える
横断的処理はinterceptorで付与する
複数アプリをHTTPの壁なしに統合する
他のPHPアプリからBEARリソースを呼び出せる
Start with one resource