NoraBear Package API Documentation

スキームベースルーティング

概要

NoraBear Packageは、BEAR.Sundayのリソーススキームごとに異なる名前空間にマッピングする SchemeAwareAdapter を提供します。

これにより、以下のような柔軟なリソース構成が可能になります:

  • api://self/users{AppName}\Resource\Api\Users
  • page://self/users{AppName}\Resource\Page\Users
  • app://self/users{AppName}\Resource\App\Users

従来の EndpointAdapter との違い

従来の EndpointAdapter

すべてのスキームを Resource\Endpoint 名前空間にマッピングします:

// すべて同じ名前空間
api://self/users  → {AppName}\Resource\Endpoint\Users
page://self/users → {AppName}\Resource\Endpoint\Users
app://self/users  → {AppName}\Resource\Endpoint\Users

新しい SchemeAwareAdapter

スキームごとに異なる名前空間にマッピングします:

// スキームごとに異なる名前空間
api://self/users  → {AppName}\Resource\Api\Users
page://self/users → {AppName}\Resource\Page\Users
app://self/users  → {AppName}\Resource\App\Users

使い方

基本的な設定(デフォルトマッピング)

デフォルトマッピングを使用する場合、api , page , app スキームが自動的に Api , Page , App 名前空間にマッピングされます:

<?php
use BEAR\Resource\SchemeCollectionInterface;
use NoraBear\Package\Scheme\SchemeMapping;
use NoraBear\Package\Scheme\SchemeAwareSchemeCollectionProvider;
use Ray\Di\AbstractModule;

class AppModule extends AbstractModule
{
    protected function configure(): void
    {
        // デフォルトマッピングを使用
        $this->bind(SchemeMapping::class)
            ->toInstance(SchemeMapping::createDefault());

        $this->bind(SchemeCollectionInterface::class)
            ->toProvider(SchemeAwareSchemeCollectionProvider::class);
    }
}

カスタムマッピング

スキームと名前空間のマッピングを自由にカスタマイズできます:

<?php
// api スキームを Endpoint 名前空間にマッピング
$mapping = new SchemeMapping([
    'api' => 'Endpoint',  // api://self/users → Resource\Endpoint\Users
    'page' => 'Page',     // page://self/users → Resource\Page\Users
]);

$this->bind(SchemeMapping::class)->toInstance($mapping);

必要なスキームだけを定義

使用するスキームだけを定義することで、不要なスキームを無効化できます:

<?php
// api スキームだけを有効化
$mapping = new SchemeMapping([
    'api' => 'Endpoint',
]);

$this->bind(SchemeMapping::class)->toInstance($mapping);

// この場合、page:// や app:// スキームは使用不可

リソースの作成

スキームごとに異なるディレクトリにリソースを配置します:

src/Resource/
├── Api/
│   └── Users.php      # api://self/users
├── Page/
│   └── Users.php      # page://self/users
└── App/
    └── Users.php      # app://self/users

APIリソースの例

<?php
namespace MyApp\Resource\Api;

use BEAR\Resource\ResourceObject;

class Users extends ResourceObject
{
    public function onGet(): static
    {
        $this->body = [
            'users' => [/* ... */]
        ];
        return $this;
    }
}

Pageリソースの例

<?php
namespace MyApp\Resource\Page;

use BEAR\Resource\ResourceObject;

class Users extends ResourceObject
{
    public function onGet(): static
    {
        // HTMLページ用のデータ
        $this->body = [
            'title' => 'ユーザー一覧',
            'users' => [/* ... */]
        ];
        return $this;
    }
}

パスの変換規則

基本的な変換

// 単純なパス
/users → Users

// ネストしたパス
/user/profile → User\Profile

// ケバブケース
/user-profile → UserProfile

// トレーリングスラッシュ
/admin/ → Admin\Index

// ルートパス
/ → Index

使用例

リソースの呼び出し

<?php
use BEAR\Resource\ResourceInterface;

class SomeClass
{
    public function __construct(
        private ResourceInterface $resource
    ) {}

    public function example(): void
    {
        // APIリソースを呼び出し
        $api = $this->resource->get('api://self/users');

        // Pageリソースを呼び出し
        $page = $this->resource->get('page://self/users');

        // Appリソースを呼び出し
        $app = $this->resource->get('app://self/users');

        // それぞれ異なるクラスが呼ばれる
    }
}

ユースケース

API専用のバリデーション

api スキームのリソースにのみOpenAPIバリデーションを適用する場合:

<?php
// OpenAPIModule側でapiスキームのみに適用
$this->bindInterceptor(
    $this->matcher->subclassesOf(ResourceObject::class)
        ->logicalAnd(new ApiResourceMatcher()),
    $this->matcher->annotatedWith(SchemaValidated::class),
    [SchemaValidateInterceptor::class]
);

マイグレーション

既存の EndpointAdapter から移行する場合

  1. リソースファイルを再配置:
# 前
src/Resource/Endpoint/Users.php

# 後
src/Resource/Api/Users.php
src/Resource/Page/Users.php
src/Resource/App/Users.php
  1. 名前空間を変更:
// 前
namespace MyApp\Resource\Endpoint;

// 後
namespace MyApp\Resource\Api;  // または Page, App
  1. AppModule のバインディングを変更:
// 前
$this->bind(SchemeCollectionInterface::class)
    ->toProvider(EndpointSchemeCollectionProvider::class);

// 後
$this->bind(SchemeCollectionInterface::class)
    ->toProvider(SchemeAwareSchemeCollectionProvider::class);

まとめ

SchemeAwareAdapter を使用することで:

  • ✅ スキームごとに異なるリソース実装を持てる
  • ✅ API、Page、Appを明確に分離できる
  • ✅ スキームごとに異なるバリデーションを適用できる
  • ✅ コードの可読性と保守性が向上

関連項目

  • はじめに
  • API Reference: NoraBear\Package\Scheme\SchemeMapping
  • API Reference: NoraBear\Package\Scheme\SchemeAwareAdapter
  • API Reference: NoraBear\Package\Scheme\SchemeAwareSchemeCollectionProvider

Search results