BEAR.Sundayを理解するためのリンクなど。
目次:
公式
- BEAR.Sunday - 公式トップ(英語)
- イントロダクション | BEAR.Sunday - 公式マニュアル(日本語)
スライド
- BEAR.Sunday Note - PHP5.4の頃のスライド。BEAR.Sundayの特徴がまとまっている
- Slide | BEAR.Sunday - 公式ページにあるPHPerKaigi 2018のスライド
- RESTの力、RESTの制約 - BEAR Blog - 以下のスライドの背景や解説記事
Qiita Advent Calendar
- BEAR.Sunday Advent Calendar 2014 - Qiita
- BEAR.Sunday Advent Calendar 2015 - Qiita
- BEAR.Sunday Advent Calendar 2017 - Qiita
- BEAR.Sunday Advent Calendar 2018 - Qiita
- BEAR.Sunday Advent Calendar 2019 - Qiita
- BEAR.Sunday Advent Calendar 2020 - Qiita
- BEAR.Sunday Advent Calendar 2021 - Qiita
- BEAR.Sunday Advent Calendar 2022 - Qiita
"○○Module"
「○○Module」は「○○をRay.Diでインジェクトできるようにする」ためのモジュールと理解するとよい。
例:
- Ray.AuraSqlModule: Aura.Sqlをインジェクトできるようにする
- Ray.AuraRouterModule: Aura.Routerをインジェクトできるようにする
- Madapaja.TwigModule: Twigをインジェクトできるようにする
- Bear.QiqModule: Qiqをインジェクトできるようにする
データベース関連
↓以下が\右を含む→ | Aura.Sql | Ray.AuraSqlModule | Aura.SqlQuery |
---|---|---|---|
Ray.QueryModule | ○ | ○ | |
Ray.MediaQuery | ○ | ○ | |
Ray.AuraSqlModule | ○ | ○ |
Aura.〜 はアプリケーション開発で使える様々なツールのパッケージ。 Aura for PHP : About
Ray.〜 はBEAR.Sunday開発者の郡山さんが作成されているパッケージ。
Aura.Sql
Aura.Sql/README.md at 5.x · auraphp/Aura.Sql · GitHub
PHPのPDOを拡張したデータベースライブラリ。
PDOを拡張したExtendedPdoは以下の特徴を持つ。
- 必要な時にデータベースに自動的に接続する (遅延接続)
- quote() で配列をクオートしてSQLの "IN" 節で使えるようにする
- perform() でハッシュで指定された引数をバインドして実行できる (prepare() 不要)
BEAR.Sunday公式の説明ページ: データベース | BEAR.Sunday
Ray.AuraSqlModule
Ray.AuraSqlModule/README.md at 1.x · ray-di/Ray.AuraSqlModule · GitHub
Aura.SqlをRay.DIでインジェクトするためのモジュール。 Aura.Sql, Ray.QueryModule, Ray.MediaQueryのためのDB接続情報を管理する。
Ray.QueryModule & Ray.MediaQuery
Ray.MediaQueryはRay.QueryModuleと同等の機能をRay.DIでインジェクトするためのモジュール。 ただしRay.QueryModuleとRay.MediaQueryの間には直接の包含関係は無い。
ドメイン層からインフラ層の実装に依存するのではなく、その逆、ドメイン層のインターフェイスにインフラ層の実装を合わせる事を特定の状況下でより効率的に行うためのパッケージがこのRay.MediaQueryです。
ドメインはインフラ層の実装や仕様に対して無知に、自由にインターフェイスを設計します。
(『ドメインとインフラ層のDIP』 Ray.MediaQuery - Qiita )
Ray.QueryModule
Ray.QueryModule/README.ja.md at 1.x
以下が含まれる。
- SqlQueryModule - SQLを実行可能な関数オブジェクトにする
- WebQueryModule - URIを実行可能な関数オブジェクトにする
- PhpQueryModule - 汎用のストレージアクセスを実行可能な関数オブジェクトにする
SQLファイルやWeb APIの設定をするだけで関数オブジェクトが作成される。 関数オブジェクト内部のコードを書く必要はない。
Ray.QueryModuleを単体で使うときは接続設定をRay.AuraSqlModuleでやる。 参照: BEAR.SundayとSQLと - Qiita
Ray.MediaQuery
Ray.MediaQuery/README.ja.md at 1.x
Ray.QueryModule相当の機能を含む。
エンティティをサポートしました。SQLの実行結果をエンティティのクラスにハイドレートして返します。https://t.co/hgXEK9EqVV pic.twitter.com/7UqMoAgpCW
— BEAR.Sunday (@BEARSunday) 2021年3月13日
Ray.MediaQueryを使うとクエリーからの戻り値をハッシュではなくエンティティとして受け取れる (Ray.QueryModuleにはこの機能は無い)。
AOP
公式ドキュメント: AOP | BEAR.Sunday
コンテントネゴシエーション
公式ドキュメント: コンテントネゴシエーション | BEAR.Sunday
同じリソースをHTML形式やJSON形式といった複数の形式で返すための仕組み。
BEAR.Acceptを使い、全体適用か部分適用を選んで使う。
- 全体適用: クライアントが指定する形式でリソースを返す
- 部分適用: リソースごとに返す形式を指定する
PageリソースをHTML形式で返すためにコンテキストを'html-app'
にすると、既定ですべてのPageリソースがHTMLで返されるようになり、対応するテンプレートが必要になる。
BEAR.Acceptの部分適用を使うと一部のリソースをHTML以外で返すことができるようになり、テンプレートが不要になる。
コンテキストが'html-app'
のとき、部分適用では以下のようにメソッドごとに@Produces
で返す形式を指定できる。
<?php /** * @return static * * @Produces({"text/html"}) * */ public function onGet(): static { ... } /** * @return static * * @Produces({"application/json"}) * */ public function onPost(string $name, string $status): static { ... }
上記のコードではGETメソッドではHTML形式で、POSTメソッドではJSON形式で結果を返す。
(HTML形式が既定なので、GETメソッドの方は@Produces
行が無くてもよい。)
HAL & ALPS
BEAR.SundayはHALとALPSをサポートしている。
参考リンク:
HAL (Hypertext Application Language)
The Hypertext Application Language
HALはリソース間ハイパーリンクについての一貫性のある簡潔な書式。
リソース表現(JSON)に以下のものを含むことでハイパーリンクを表現する。
_links
- リンク_embedded
- 含まれるリソース
BEAR.SundayでHAL形式の表現を返すにはコンテキストに hal
を指定し、@Embed
アノテーションでリソースを埋め込む。
ALPS (Application-Level Profile Semantics)
ALPSはリソースのフィールドの意味や型、遷移の属性を表現する。
- 意味や型 - Schema.org, IANA, Activity Stream などを使って表現する
- 遷移の属性 - safe, unsafe, idempotent で表現する
BEAR.Sundayでは Fake
コンテキストを作成し、FakeJSONを @JsonSchema
で読み込ませることで偽のデータを返すFakeサーバを立ち上げたり(サーバが完成する前にクライアントを作成することができる)、渡される値を自動バリデートすることができる。
雑多な調査
参考資料:
- BEAR.Sundayをコードリーディングしたのでメモ程度にアウトプットする - OTOBANK Engineering Blog
- Re: BEAR.Sundayをコードリーディングしたのでメモ程度にアウトプットする - BEAR Blog
URIをリソースにマップする処理
URIをリソースにマップしているのは BEAR\Resource\AppAdapter
の get
メソッド。
<?php public function get(AbstractUri $uri): ResourceObject { if (substr($uri->path, -1) === '/') { // --- (1) $uri->path .= 'index'; } $path = str_replace('-', '', ucwords($uri->path, '/-')); // --- (2) /** @var ''|class-string $class */ $class = sprintf('%s\Resource\%s', $this->namespace, str_replace('/', '\\', ucwords($uri->scheme) . $path)); // --- (3) try { $instance = $this->injector->getInstance($class); // --- (4) assert($instance instanceof ResourceObject); } catch (Unbound $e) { throw $this->getNotFound($uri, $e, $class); } return $instance; }
コンテキストをURIスキームにマップする処理
コンテキストが http
以外の場合:
BEAR\Package\Context\ApiModule
<?php protected function configure(): void { $this->bind()->annotatedWith(DefaultSchemeHost::class)->toInstance('app://self'); $this->bind()->annotatedWith(ContextScheme::class)->toInstance('app://self'); }
コンテキストが http
の場合:
BEAR\Sunday\Provide\Router\RouterModule
<?php protected function configure(): void { $this->bind(RouterInterface::class)->to(WebRouter::class); $this->bind()->annotatedWith(DefaultSchemeHost::class)->toInstance('page://self'); }
ここで設定した DefaultSchemeHost
が、たとえば BEAR\Package\Provide\Router\WebRouter
などで
<?php /** * @DefaultSchemeHost("schemeHost") */ #[DefaultSchemeHost('schemeHost')] public function __construct(string $schemeHost, HttpMethodParamsInterface $httpMethodParams) {
このように $schemeHost にバインドされて使われている。
DockerfileでAPCuを有効にする
DockerのAlpine LinuxコンテナでAPCu(APCキャッシュ)を有効にする時はDockerfileに次の記述を入れる。
# install packages for apcu RUN apk --update --no-cache add autoconf g++ make && \ pecl install apcu && \ echo -e "extension=apcu.so\napcu.enabled=1\napc.enable_cli=1" > ${PHP_INI_DIR}/conf.d/apcu.ini