技術
BEAR.Sundayの特徴的な技術と機能を以下の章に分けて解説します。
アーキテクチャと設計原則
リソース指向アーキテクチャ (ROA)
BEAR.SundayのROAは、WebアプリケーションでRESTful APIを実現するアーキテクチャです。これはBEAR.Sundayの設計原則の核となるものであり、ハイパーメディアフレームワークであると同時にサービスとしてのオブジェクト(Object as a service)として扱います。Webと同様に、全てのデータや機能をリソースとみなし、GET、POST、PUT、DELETEなどの標準化されたインターフェースを通じて操作します。
URI
URI(Uniform Resource Identifier)はWebの成功の鍵となる要素であり、BEAR.SundayのROAの中核でもあります。アプリケーションが扱う全てのリソースにURIを割り当てることで、リソースを識別し、アクセスしやすくなります。URIは、リソースの識別子として機能するだけでなく、リソース間のリンクを表現するためにも使用されます。
ユニフォームインターフェース
リソースへのアクセスはHTTPのメソッド(GET, POST, PUT, DELETE)を用いて行われます。これらのメソッドはリソースに対して実行できる操作を規定しており、リソースの種類にかかわらず共通のインターフェースを提供します。
ハイパーメディア
BEAR.SundayのROAでは、各リソースがハイパーリンクを通じてアフォーダンス(クライアントが利用可能な操作や機能)を提供します。これらのリンクは、クライアントが利用できる操作を表し、アプリケーション内をナビゲートする方法を示します。
状態と表現の分離
BEAR.SundayのROAでは、リソースの状態とそのリソース表現が明確に分離されています。リソースの状態はリソースクラスで管理され、リソースにインジェクトされたレンダラーが様々な形式(JSON, HTMLなど)でリソースの状態をリソース状態表現に変換します。ドメインロジックとプレゼンテーションロジックは疎結合で、同じコードでもコンテキストによって状態表現の束縛を変更すると表現も変わります。
MVCとの相違点
BEAR.SundayのROAは、従来のMVCアーキテクチャとは異なるアプローチを採用しています。 MVCはモデル、ビュー、コントローラーの3つのコンポーネントでアプリケーションを構成し、コントローラーはリクエストオブジェクトを受け取り、一連の処理を制御してレスポンスを返します。一方、リソースはリクエストメソッドにおいて、単一責任原則(SRP)に従い、リソースの状態の指定のみを行い、表現には関与しません。
MVCではコントローラーとモデルの関係に制約はありませんが、リソースはハイパーリンクとURIを使用した他のリソースを含める明示的な制約があります。これにより、呼び出されるリソースの情報隠蔽を維持しながら、宣言的な方法でコンテンツの内包関係とツリー構造を定義できます。
MVCのコントローラーはリクエストオブジェクトから手動で値を取得しますが、リソースは必要な変数をリクエストメソッドの引数として宣言的に定義します。そのため、入力バリデーションもJsonSchemaを使用して宣言的に実行され、引数とその制約が文書化されます。
依存性の注入 (DI)
依存性の注入(Dependency Injection, DI)は、オブジェクト指向プログラミングにおけるアプリケーションの設計と構造を強化するための重要な手法です。DIの中心的な目的は、アプリケーションの機能を複数の独立したドメインまたは役割を持つコンポーネントに分割し、それらの間の依存関係を管理することです。
DIは、1つの機能(関心事、責務)を複数の機能に水平分割するのに役立ちます。分割された機能は「依存」として各部分を独立して開発、テストできるようになります。単一責任原則に基づき明確な責任と役割を持つそれらの依存を外部から注入することで、オブジェクトの再利用性とテスト性を向上させます。また依存は他の依存へと垂直にも分割され、依存関係のツリーを形成します。
BEAR.SundayのDIはRay.Diという独立したパッケージを使用しており、Google社製のDIフレームワークであるGuiceの設計思想を取り入れ、ほぼ全ての機能をカバーしています。
その他に以下の特徴があります。
- コンテキストにより束縛を変更し、テスト時に異なる実装を注入できます。
- アトリビュートによる設定でコードの自己記述性が高まります。
- Ray.Diはコンパイル時に依存性の解決を行うため、ランタイム時のパフォーマンスが向上します。これは、ランタイム時に依存性を解決する他のDIコンテナとは異なる点です。
- オブジェクトの依存関係をグラフで可視化できます。例)ルートオブジェクト
アスペクト指向プログラミング (AOP)
アスペクト指向プログラミング(AOP)は、ビジネスロジックなどの本質的な関心と、ログやキャッシュなどの横断的関心を分離することで、柔軟なアプリケーションを実現するパターンです。横断的関心とは、複数のモジュールやレイヤーにまたがって存在する機能や処理のことを指します。探索条件に基づいた横断的処理の束縛が可能で、コンテキストに基づいた柔軟な構成が可能です。
BEAR.SundayのAOPはRay.Aopという独立したパッケージを使用しており、PHPのアトリビュートをクラスやメソッドに付与して、横断的処理を宣言的に束縛します。Ray.Aopは、JavaのAOP Allianceに準拠しています。
AOPは「既存の秩序を壊す強い力」と誤解されがちな技術です。その存在意義は制約を超えた力の行使などではなく、マッチャーを使った探索的な機能の割り当てや横断的処理の分離など、オブジェクト指向が不得意とする分野の補完にあります。AOPはアプリケーションの横断的な制約を作ることのできる、つまりアプリケーションフレームワークとして機能するパラダイムです。
パフォーマンスとスケーラビリティ
モダンCDNとの統合によるROAベースのイベントドリブンコンテンツ戦略
BEAR.Sundayは、リソース指向アーキテクチャ(ROA)を中核に、Fastlyなどのインスタントパージ可能なCDNと統合してイベントドリブンなキャッシュ戦略をとります。TTL(Time to Live)でキャッシュを期限切れにするのではなく、リソースの状態が変わったイベントに応じて、CDNとサーバーサイドのキャッシュ、およびETag(エンティティタグ)を即座に無効化します。
CDNに有効期限のないコンテンツを置くため、PHPやDBが落ちてもコンテンツは配信され続けます。SPOF(Single Point of Failure)がなくなり、ダイナミックコンテンツでもスタティックコンテンツと同じ分散キャッシングが効きます。これはWebが1990年代から持っていた分散キャッシュの原則を、現代のCDNで取り戻すものです。
セマンティックメソッドと依存によるキャッシュ無効化
BEAR.SundayのROAでは、各リソース操作にセマンティック(意味的な役割)が与えられています。例えば、GETメソッドはリソースを取得し、PUTメソッドはリソースを更新します。これらのメソッドがイベントドリブン方式で連携し、関連するキャッシュを効率的に無効化します。例えば、特定のリソースが更新された際には、そのリソースを必要とするリソースのキャッシュが無効化されます。これにより、データの一貫性と新鮮さを保ち、ユーザーに最新の情報を提供します。
ETagによる同一性確認と高速な応答
システムがブートする前にETagを設定することで、コンテンツの同一性を迅速に確認し、変更がない場合は304 Not Modified応答を返してネットワークの負荷を最小化します。
ドーナッツキャッシュとESIによる部分的な更新
ドーナッツキャッシュ戦略では、ESI(Edge Side Includes)を使ってCDNエッジで部分的にコンテンツを更新します。ページ全体を再キャッシュせず、必要な部分だけを動的に更新するため、キャッシュ効率が上がります。
ランタイム最適化
BEAR.Sundayは、どのサーバー構成でもフレームワークのオーバーヘッドを最小化する設計になっています。
DIの依存解決はコンパイル時に完了し、実行時にコンテナを参照しません。アプリケーション全体は1つのルートオブジェクト変数として生成され、リクエストを超えて再利用されます。php-fpm構成では、コンパイル済みの依存グラフとopcacheにより高速にブートストラップします。
Swoole構成では、永続ワーカーによりブートストラップは初回の1回だけです。リクエストはコルーチンコンテキストで分離されるため、スーパーグローバルに依存せずに並行処理できます。次に述べる透過的な並列実行と組み合わせれば、I/O待ち時間も短くなります。
読み取り専用の成果物
コンパイルはビルド時の作業です。オブジェクトグラフはデプロイ前に解決され、DIの設定ミスはビルドの段階で検出されるため、本番環境に持ち込まれることはありません。起動時に行うのはコンパイル済みの成果物を読み込むことだけで、ファイルツリーへの書き込みは一切発生しません。そのため成果物は読み取り専用のままデプロイでき、サーバーレスやイミュータブルコンテナのように書き込み可能な場所が限られた環境でも、書き込み先を宣言するだけで動作します。コールドスタートに要するのは成果物の読み込み時間のみです(リソース5個のアプリケーションで、再コンパイルが0.38秒に対し、成果物からの読み込みは0.018秒)。スケールアウトで追加されたインスタンスはすべて同じ成果物から起動するため、常に同じ結果を返します。
成果物は1つのPharファイルにまとめることもできます。コード、vendor/、コンパイル済みのDIスクリプトが1つのアーカイブに収まるため、デプロイはファイルを1つコピーするだけ、ロールバックは1つ前のファイルに戻すだけです。アーカイブに何を含めるかはフレームワークが決定し、未コンパイルのビルドや自身のツリーに書き込むビルドは、アーカイブ作成前に拒否されます。インポートした複数のアプリケーションも同じアーカイブに含められます。静的ビルドしたPHPバイナリを同梱すればホストにPHPをインストールする必要がなくなり、コマンドラインアプリケーションであればPHPとアーカイブを1つの実行ファイルにまとめることも可能です。さらに、同じアーカイブはブラウザ上でも動作します。この場合、サーバー側にPHPランタイムもアプリケーションサーバーも必要ありません。
透過的な並列実行
BEAR.Sundayでは、URIは単なる通信プロトコルや場所ではなく「意図」を表現します。app://self/userは「ユーザー情報が欲しい」という意図だけを示し、それがMySQLから取得されるのかRedisから取得されるのかは隠蔽されています。
この「What(何を)」と「How(どう)」の完全分離により、アプリケーションコードを一切変更することなく、#[Embed]で埋め込まれた複数のリソースを並列に取得できます。10年前に書かれたリソースクラスも、Moduleを追加するだけで並列実行の恩恵を受けられます。
サーバー環境の制約に応じて、ext-parallel(スレッドプール)とSwoole(コルーチン)の2つのランタイムが用意されており、どちらを選択してもアプリケーションコードは変更不要です。開発時は通常のPHPとしてデバッグし、本番では設定の切り替えだけで並列実行に移行できます。SQLについても同様です。SQL文ごとにリソースを分け、上位のリソースから#[Embed]で束ねるだけで、ランタイムに応じて複数のSQLが並列に発行されます。利用側はリソースを組み合わせるだけで済みます。
遅延リソース実行
重い後続処理は、レスポンスを返した後に実行できます。リソースは202 Acceptedを返し、インデックスの更新や通知の送信といった処理は、レスポンスがクライアントに届いた後に実行されます。レスポンスが先に返されるかどうかはSAPIに依存します。PHP-FPMとLiteSpeedでは接続が即座に解放されてレスポンスが返りますが、Apache mod_phpではベストエフォートとなります。リソースが宣言するのは「何を」遅延させるかだけで、「いつ・どこで」実行するかはリソースの外側で決定されます。並列実行と同様に、リソースのコード自体は変更不要です(遅延リソース実行、Alpha)。
開発者エクスペリエンス
テストの容易性
BEAR.Sundayは、以下の設計上の特徴により、テストが容易で効果的に行えます。
- 各リソースは独立していて、RESTのステートレスリクエストの性質によりテストが容易です。 リソースの状態と表現が明確に分離されているため、HTML表現の場合でもリソースの状態をテストできます。
- ハイパーメディアのリンクをたどりながらAPIのテストを行え、PHPとHTTPの同一コードでテストできます。
- コンテキストによる束縛により、テスト時に異なる実装を束縛できます。
Application as Documentation
BEAR.Sundayでは、アプリケーション自体がドキュメントです。コードから複数形式のドキュメントを自動生成します。
- ApiDoc HTML: 開発者向けリファレンス
- OpenAPI 3.1: ツールチェーン統合用
- JSON Schema: 情報モデル定義
- llms.txt: AI可読なアプリケーション概要
ALPSプロファイルをSSOT(Single Source of Truth)として使用する場合、アプリケーションのセマンティクス(語彙、状態遷移、操作の意味)を先に定義し、それを元にコードを生成できます。同じドキュメントが読み手によって異なる意味を持ち、開発者はエンドポイントを、アーキテクトは状態遷移を、AIはオントロジーを読み取ります。
視覚化とデバッグ
リソースが自身でレンダリングする技術的特徴を生かし、開発時にHTML上でリソースの範囲を示し、リソース状態をモニターできます。また、PHPコードやHTMLテンプレートをオンラインエディターで編集し、リアルタイムに反映することもできます。
AIエージェントとの協働
AIエージェントは、BEAR.Sundayの規約に沿ってコードの生成やレビューを行います。BEAR.Skillsは、リソースの生成、ハイパーメディアリンクの追加、品質レビューといった作業をClaude Codeのスキルとして提供します。BEAR.Kataは、目的の機能を実装する際にどのファイルを参照すべきかを示す実装パターン集です。詳細はAIアシスタントを参照してください。
拡張性と統合
PHPインターフェイスとSQL実行の統合
BEAR.SundayではPHPのインターフェイスを通じて、データベースとのやり取りを行うSQL文の実行を簡単に管理できます。クラスを実装することなく、PHPインターフェイスに直接SQLの実行オブジェクトを束縛できます。ドメインとインフラストラクチャーの境界をPHPインターフェイスで結びます。
引数には型も指定でき、不足している分はDIが依存解決を行い文字列として利用されます。SQL実行に現在時刻が必要な場合でも渡す必要はなく、自動束縛されます。クライアントが全ての引数を渡す責任がなく、コードの簡潔さを保てます。
また、SQLの直接管理は、エラー発生時のデバッグを容易にします。SQLクエリの動作を直接観察し、問題の特定と修正を迅速に行えます。
他システムとの統合
BEAR.Sundayのリソースは様々なインターフェースから利用可能です。Webインターフェースに加え、コンソールからリソースに直接アクセスでき、ソースコードを変えずにWebとコマンドライン双方から同じリソースを利用できます。さらにBEAR.CLIを使用することで、リソースを独立したUNIXコマンドとして配布することも可能です。また、同一PHPランタイム内で異なるBEAR.Sundayアプリケーションを並行実行できることで、マイクロサービスを構築することなく独立した複数のアプリケーションを連携できます。
リソースをAIのツールに
リソースは、AIエージェントが利用するツールにもなります。BEAR.ToolUseはResourceObjectからツール定義を生成し、パラメーターの説明や制約をJSON Schema、PHPDoc、ALPSプロファイルから組み立てます。AI向けに別途関数群を用意するのではなく、アプリケーションが実際に持つ機能がそのままツールになります。
どの操作をエージェントに自由に呼ばせてよく、どの操作に人の確認が必要かは、RESTのメソッドの意味論を根拠に判断します。safeかつidempotentなGETは自由に呼び出させ、状態を変更する操作には#[Tool(confirm: true)]を付与します。これにより、バインドされた確認ハンドラーが実行前に人へ確認を求めます。この確認は認証や認可の代わりになるものではなく、それらの上に人の判断をもう一段重ねるものです。新たな仕組みを追加したわけではありません。URI、ユニフォームインターフェース、型、JSON Schema、ALPSは、最初からツール定義としての形を備えていたのです。
ストリーム出力
リソースのボディにファイルのポインタなどのストリームを割り当てることで、メモリ上では扱えない大規模なコンテンツを出力できます。その際、ストリームは通常の実変数と混在させることも可能で、大規模なレスポンスを柔軟に出力できます。
他のシステムからの段階的移行
BEAR.SundayはComposerパッケージとして既存のコードベースに組み込めます。LaravelやSymfonyで動いているシステムに、一度に置き換えることなく機能単位で導入できます。
技術移行の柔軟性
BEAR.Sundayは、将来の技術的変化や要件の進化に備えて投資を保護します。このフレームワークから別のフレームワークや言語に移行する必要がある場合でも、構築したリソースは無駄になりません。PHP環境では、BEAR.SundayアプリケーションをComposerパッケージとして統合して継続的に利用できます。また、BEAR.Thriftを使用すると、他の言語からBEAR.Sundayリソースに効率的にアクセスでき、Thriftを使用しない場合でもHTTPでアクセスが可能です。さらに、SQLコードの再利用も容易です。
また、使用しているライブラリが特定のPHPバージョンに強く依存している場合でも、BEAR.Thriftを使用して異なるバージョンのPHPを共存させることができます。
設計思想と品質
標準技術の採用と独自規格の排除
BEAR.Sundayは、可能な限り標準技術を採用し、フレームワーク独自の規格やルールを排除するという設計思想を持っています。例えば、デフォルトでJSON形式とwwwフォーム形式のHTTPリクエストのコンテントネゴシエーションをサポートし、エラーレスポンスにはvnd.error+jsonメディアタイプ形式を使用します。リソース間のリンクにはHAL(Hypertext Application Language)を採用し、バリデーションにはJsonSchemaを用いるなど、標準的な技術や仕様を積極的に取り入れています。
一方で、独自のバリデーションルールや、フレームワーク特有の規格・ルールは可能な限り排除しています。
オブジェクト指向原則
BEAR.Sundayはアプリケーションを長期的にメンテナンス可能とするためのオブジェクト指向原則を重視しています。
継承より合成
継承クラスよりコンポジションを推奨します。一般に子クラスから親クラスのメソッドを直接呼び出すことは、クラス間の結合度を高くする可能性があります。設計上、ランタイムで継承が必要な抽象クラスはリソースクラスのBEAR\Resource\ResourceObjectのみですが、これもResourceObjectのメソッドは他のクラスが利用するためだけに存在します。ユーザーが継承したフレームワークの親クラスのメソッドをランタイムに呼び出すことは、BEAR.Sundayではどのクラスにもありません。
全てがインジェクション
フレームワークのクラスが「設定ファイル」や「デバッグ定数」を実行中に参照して振る舞いを決定することはありません。振る舞いに応じた依存が注入されます。これにより、アプリケーションの振る舞いを変更するためには、コードを変更する必要がなく、インターフェイスに対する依存性の実装の束縛を変更するだけで済みます。APP_DEBUGやAPP_MODE定数は存在しません。ソフトウェアが起動した後に現在どのモードで動作しているか知る方法はありませんし、知る必要もありません。
後方互換性の永続的確保
BEAR.Sundayは最初のリリース以来、後方互換性を壊さずに進化を続けています。フレームワークが互換性を壊すたびに、アプリケーション側は改修とテストをやり直すことになります。その負担が生じないようにしてきました。
BEAR.Sundayでは、セマンティックバージョニングを採用するだけでなく、破壊的な変更を伴うメジャーバージョンアップを行いません。新しい機能の追加や既存機能の変更が既存のコードに影響を与えることを防いでいます。古くなって使われなくなったコードには「deprecated」の属性が与えられますが、削除されることはなく、既存のコードの動作にも影響を与えません。その代わりに、新しい機能が追加され、進化が続けられます。
非環式依存原則
非環式依存原則(ADP)とは、依存関係が一方向であり、循環していないことを意味します。BEAR.Sundayフレームワークはこの原則に基づき、一連のパッケージで構成されており、大きなフレームワークパッケージが小さなフレームワークパッケージに依存する階層構造を持っています。各レベルはそれを包含する他のレベルの存在自体を知る必要はなく、依存関係は一方向のみで循環しません。例えば、Ray.AopはRay.Diの存在すら知りませんし、Ray.DiはBEAR.Sundayの存在を知りません。

後方互換性が保持されているため、各パッケージは独立して更新できます。また、他のフレームワークで見られるような全体をロックするバージョン番号は存在せず、オブジェクト間を横断する依存関係を持つオブジェクトプロキシーの機構もありません。
この非環式依存原則はDI(依存性注入)の原則と調和しており、BEAR.Sundayが起動する際に生成されるルートオブジェクトも、この非環式依存原則の構造に従って構築されます。
ランタイムも同様です。リソースにアクセスが行われる際、まずメソッドに結び付けられたAOPアスペクトの横断的な処理が行われ、その後でメソッドがリソースの状態を決定しますが、この時点でメソッドは結び付けられたアスペクトの存在を認識していません。リソースの状態に埋め込まれたリソースも同じです。それらは外側の層や要素の知識を持っていません。関心の分離が明確にされています。
コード品質
高品質なアプリケーションを提供するため、BEAR.Sundayフレームワークも高い水準でコード品質を維持するよう努めています。
- フレームワークのコードは静的解析ツールのPsalmとPHPStan双方で最も厳しいレベルを適用しています。
- テストカバレッジ100%を保持しており、タイプカバレッジもほぼ100%です。
- 原則的にイミュータブルなシステムであり、テストでも毎回初期化が不要なほどクリーンです。SwooleのようなPHPの非同期通信エンジンの性能を最大限に引き出します。
アーキテクチャによるセキュリティ解析
BEAR.Sundayのアーキテクチャは、セキュリティ解析を根本的に容易にします。
すべてのエンドポイントはonGet、onPostメソッドを持つResourceObjectであり、入力はJSON Schemaで宣言され、依存関係はコンストラクタインジェクションで明示されます。隠れたマジックやグローバル状態がないため、静的解析ツールは完全なデータフローを追跡できます。
この宣言的なアーキテクチャにより、SAST(静的解析)、DAST(動的テスト)、テイント解析、AI監査を組み合わせた多層的なセキュリティスキャンが可能です。汎用ツールでは検出困難な脆弱性も、フレームワークを理解した専用ツールが検出します。
BEAR.Sundayのもたらす価値
開発者にとっての価値
-
生産性の向上: 堅牢な設計パターンと原則に基づく、時間が経過しても変わることのない制約により、開発者はコアとなるビジネスロジックに集中できます。
-
チームでの協業: 開発チームに一貫性のあるガイドラインと構造を提供することで、異なる開発者のコードを疎結合のまま統一的に保ち、コードの可読性とメンテナンス性を向上させます。
-
柔軟性と拡張性: BEAR.Sundayがライブラリを含まないという方針により、開発者はコンポーネントの選択において高い柔軟性と自由度を得られます。
-
テストの容易性: リソースはステートレスで、テストごとに初期化が要りません。束縛を差し替えればテスト用の実装を注入できます。
ユーザーにとっての価値
-
高いパフォーマンス: 最適化された高速起動とCDNを中心としたキャッシュ戦略により、ユーザーには高速で応答性の優れたエクスペリエンスが提供されます。
-
信頼性と可用性: CDNを中心としたキャッシュ戦略により、単一障害点(SPOF)を最小化し、ユーザーに安定したサービスを提供し続けることができます。
-
使いやすさ: 接続性が高いため、他の言語やシステムと連携しやすくなっています。また、リソースをCLIツールとして提供することで、エンドユーザーは複雑な環境設定なしにアプリケーションの機能を利用できます。PHPを同梱した単一の実行ファイルとして配布することも可能です。
ビジネスにとっての価値
-
開発コストの削減: JSON Schemaによる入力検証やAPIドキュメントは自動生成されるため、手書きのバリデーションコードやドキュメントに工数がかかりません。
-
保守コストの削減: 後方互換性を重視するアプローチにより、技術的な継続性を高め、変更対応にかかる時間とコストを最小限に抑えます。
-
高い拡張性: 振る舞いの変更は束縛の変更で済み、ビジネスロジックのコードには手を入れません。
まとめ
優れた制約は不変です。BEAR.SundayはWebの原則に基づいた制約を提供します。 その制約の中で、開発者は本質的な問題だけに向き合えます。
