目次

PSR-13: Link definition interfaces

y2sunlight 2020-06-23

本章は、若干の補足を加筆してはいるものの単にPSRのサイトを日本語に翻訳したものに過ぎません。英語が堪能な方は原文をご参照下さい。翻訳に当たっては、基本的に機械翻訳を使い、理解できない部分は独断で意訳しております。拙い訳では御座いますが恥を忍んで投稿しておりますので、ご指摘など御座いましたらコメントを頂ければ幸いです。

関連記事


PSR-13: リンク定義インターフェース

原文より翻訳 PSR-13: Link definition interfaces 2020-07-14 現在

ハイパーメディアリンクは、HTMLコンテキストとさまざまなAPIフォーマットコンテキストの両方で、Webのますます重要な部分になりつつあります。しかしながら、単一の一般的なハイパーメディアフォーマットは無く、フォーマット間のリンクを表す一般的な方法もありません。

この仕様は、PHP開発者に、ハイパーメディアリンクを表す簡単で一般的な方法を提供することを目的としています。それは使用されるシリアル化フォーマットとは独立しています。これにより、システムは応答を、ハイパーメディアリンクで1つまたは複数のワイヤーフォーマットにシリアル化することができます。それは、それらのリンクが何であるかを決定するプロセスとは独立しています。

このドキュメントのキーワード MUST , MUST NOT , REQUIRED , SHALL , SHALL NOT , SHOULD , SHOULD NOT , RECOMMENDED , MAY 及び OPTIONAL は、 RFC 2119で説明されているように解釈して下さい。

RFC 2119の説明
MUST, REQUIRED, SHALL — 絶対必要
MUST NOT, SHALL NOT — 絶対禁止
SHOULD, RECOMMENDED — 推奨(但し、無視できる特定の正当な理由が存在するかもしれない)
SHOULD NOT — 推奨できない(但し、許可できる特定の正当な理由が存在するかもしれない)
MAY, OPTIONAL — オプション

References


1. 仕様

1.1 基本的なリンク

ハイパーメディアリンクは、少なくとも次のもので構成されます:

使用されるフォーマットに応じて、リンクの他のさまざまな属性が存在する場合があります。追加の属性は十分に標準化されていないか普遍的ではないため、この仕様はそれらを標準化することを目指していません。

この仕様の目的の為に、次の定義が適用されます。


1.2 属性

すべてのリンクには、URIおよび関係以外に、追加属性が含まれる場合があります( MAY )。ここで許可される値の正式なレジストリはなく、値の有効性はコンテキストに依存し、多くの場合、特定のシリアル化フォーマットに依存します。一般的にサポートされている値には、「hreflang」、「title」、「type」があります。

シリアライザは、シリアル化フォーマットで必要なら、リンクオブジェクトの属性を省略してもよい( MAY )。ただし、シリアライザは、シリアル化フォーマットの定義で妨げられない限り、ユーザー拡張を可能にするために、提供されるすべての属性をエンコードすべきです( SHOULD )。

いくつかの属性(通常は hreflang )は、そのコンテキストで複数回現れることがあります。従って、属性値は単純な値ではなく値の配列である場合があります( MAY )。シリアライザは、シリアル化されたフォーマット(スペース区切りのリスト、カンマ区切りのリストなど)に適した形式でその配列をエンコードできます( MAY )。与えられた属性が特定のコンテキストで複数の値を持つことが許可されていない場合、シリアライザは提供された最初の値を使用し、後続のすべての値を無視する必要があります( MUST )。

属性値がブール値 true の場合、シリアライザは、適切且つシリアル化フォーマットでサポートされている場合は、省略された形を使用できます( MAY )。例えば、属性の存在がブール値としての意味を持つ場合、HTMLは属性が値を持つことを許可しません。このルールは、属性がブール値 true の場合だけに適用され、PHPの整数 1 のような他の「真を表す」値に対しては適用されません。   属性値がブール値 false の場合、シリアライザは、結果の意味論的な意味を変更しない限り、属性を完全に省略すべきです( SHOULD )。このルールは、属性がブール値 false の場合にのみ適用され、PHPの整数 0 のような他の「偽を表す」値に対しては適用されません。


1.3 関係

リンク関係は文字列として定義されます。それは、パブリックに定義された関係の場合は単純なキーワード、またはプライベートな関係の場合は絶対URIのいずれかです。

単純なキーワードが使用されている場合、次のIANA( Internet Assigned Number Authority )レジストリのキーワードと一致すべきです( SHOULD )。

オプションで microformats.org レジストリを使用できますが( MAY )、これはすべてのコンテキストで有効であるとは限りません。

上記のレジストリまたは同様のパブリックレジストリのいずれかで定義されていない関係は、「プライベート」と見なされます。つまり、特定のアプリケーションまたはユースケースに固有です。このような関係では、絶対URIを使用する必要があります( MUST )。


1.4 リンクテンプレート

RFC 6570 は、URIテンプレートの形式を定義します。つまり、クライアントツールによって提供される値で埋められることが予想されるURIのパターンを定義しています。いくつかのハイパーメディア形式はテンプレート化されたリンクをサポートしていますが、サポートしていないものもあり、リンクがテンプレートであることを示す特別な方法を持っている場合があります。URIテンプレートをサポートしない形式のシリアライザは、遭遇するテンプレート化されたリンクをすべて無視する必要があります( MUST )。


1.5 進化可能なプロバイダー

場合によっては、リンクプロバイダーは追加されたリンクを持つ機能が必要になることがあります。他の場合では、リンクプロバイダーは必ず読み取り専用であり、実行時に他のデータソースからリンクが派生します。そのため、変更可能なプロバイダーは、オプションで実装できるセカンダリーインターフェースとなります。

さらに、PSR-7 Responseオブジェクトの様ないくつかのリンクプロバイダーオブジェクトは、設計上不変です。つまり、それらへのリンクをインプレースで追加するメソッドには互換性がありません。従って、EvolvableLinkProviderInterface の単一のメソッドでは、元のオブジェクトと同じですが、追加のリンクオブジェクトが含まれた新しいオブジェクトを返す必要があります。


1.6 進化可能なリンクオブジェクト

リンクオブジェクトは、ほとんどの場合、値オブジェクトです。そのため、PSR-7の値オブジェクトと同じ方法でそれらを進化させることは、有用なオプションです。そのため、1回の変更で新しいオブジェクトインスタンスを生成するメソッドを提供する EvolvableLinkInterface が追加されています。同じモデルが PSR-7 で使用されており、PHP の copy-on-write 動作のおかげで、CPUとメモリの効率が向上しています。

ただし、リンクのテンプレート値は href 値にのみ基づいているので、テンプレート値に対しては進化可能な方法はありません。それは、独自に設定することはできませんが( MUST NOT )、href値が RFC 6570 リンクテンプレートであるかどうかに由来しています。


2. パッケージ

The interfaces and classes described are provided as part of the psr/link package.

説明されているインターフェースとクラスは、psr/link パッケージの一部として提供されます。


3. インターフェース

LinkInterface.php
<?php
 
namespace Psr\Link;
 
/**
 * 読み取り可能なリンクオブジェクト。
 */
interface LinkInterface
{
    /**
     * リンクのターゲットを返します。
     *
     *
     * ターゲットリンクは次のいずれかである必要があります。
     * - RFC 5988で定義されている絶対URI。
     * - RFC 5988で定義されている相対URI。相対リンクのベースは、クライアントによるコンテキストに
     *   基づいて認識されていると想定されています。
     * - RFC 6570で定義されているURIテンプレート。
     *
     * URIテンプレートが返される場合、isTemplated()はTrueを返さなければなりません (MUST)
     *
     * @return string
     */
    public function getHref();
 
    /**
     * これがテンプレートリンクかどうかを返します。
     *
     * @return bool
     *   このリンクオブジェクトがテンプレート化されている場合はTrue、そうでない場合はFalse。
     */
    public function isTemplated();
 
    /**
     * リンクの関係タイプを返します。
     *
     * このメソッドは、リンクに対し0個以上の関係タイプを文字列の配列として返します。
     *
     * @return string[]
     */
    public function getRels();
 
    /**
     * ターゲットURIを説明する属性のリストを返します。
     *
     * @return array
     *  属性のKey-Valueリスト。キーは文字列で、値はPHPプリミティブまたはPHP文字列の配列です。 
     *  値が見つからない場合は、空の配列を返す必要があります。
     */
    public function getAttributes();
}


EvolvableLinkInterface.php
<?php
 
namespace Psr\Link;
 
/**
 * 進化可能なリンク値オブジェクト。
 */
interface EvolvableLinkInterface extends LinkInterface
{
    /**
     * 指定されたhrefを持つインスタンスを返します。
     *
     * @param string $href
     *   含めるhref値。 次のいずれかである必要があります。
     *     - RFC 5988で定義されている絶対URI。
     *     - RFC 5988で定義されている相対URI。相対リンクのベースは、クライアントによるコンテキストに
     *       基づいて認識されていると想定されています。
     *     - RFC 6570で定義されているURIテンプレート。
     *     - 上記の値の1つを生成する__toString()を実装するオブジェクト。
     *
     * 実装ライブラリは、渡されたオブジェクトが後で返されるのを待つのではなく、
     * すぐに文字列に評価する必要があります( SHOULD )。
     *
     * @return static
     */
    public function withHref($href);
 
    /**
     * 指定された関係を含むインスタンスを返します。
     *
     * 指定されたrelがすでに存在する場合、このメソッドはエラーなしで正常に戻る必要があります。
     * 但し、もう一度relを追加する必要はありません。
     *
     * @param string $rel
     *   追加する関係の値。
     * @return static
     */
    public function withRel($rel);
 
    /**
     * 指定された関係を除外したインスタンスを返します。
     *
     * 指定されたrelが既に存在しない場合、このメソッドはエラーなしで正常に戻る必要があります( MUST )。
     *
     * @param string $rel
     *   除外する関係値
     * @return static
     */
    public function withoutRel($rel);
 
    /**
     * 指定された属性が追加されたインスタンスを返します。
     *
     * 指定された属性がすでに存在する場合は、新しい値で上書きされます。
     *
     * @param string $attribute
     *   含める属性
     * @param string $value
     *   設定する属性の値
     * @return static
     */
    public function withAttribute($attribute, $value);
 
    /**
     * 指定された属性を除外したインスタンスを返します。
     *
     * 指定された属性が存在しない場合、このメソッドはエラーなしで正常に戻る必要があります( MUST )。
     *
     * @param string $attribute
     *   削除する属性
     * @return static
     */
    public function withoutAttribute($attribute);
}


LinkProviderInterface.php
<?php
 
namespace Psr\Link;
 
/**
 * リンクプロバイダーオブジェクト
 */
interface LinkProviderInterface
{
    /**
     * LinkInterfaceオブジェクトのiterableを返します。
     *
     * iterableは、配列または任意のPHP \Traversableオブジェクトです。利用可能なリンクがない場合は、
     * 空の配列 または \Traversableを返す必要があります( MUST )。
     *
     * @return LinkInterface[]|\Traversable
     */
    public function getLinks();
 
    /**
     * 特定の関係を持つLinkInterfaceオブジェクトのiterableを返します。
     *
     * iterableは、配列または任意の PHP \Traversableオブジェクトです。その関係を持つリンクがない場合は、
     * 空の配列 または \Traversable を返す必要があります。( MUST )
     *
     * @return LinkInterface[]|\Traversable
     */
    public function getLinksByRel($rel);
}


EvolvableLinkProviderInterface.php
<?php
 
namespace Psr\Link;
 
/**
 * 進化可能なリンクプロバイダー値オブジェクト
 */
interface EvolvableLinkProviderInterface extends LinkProviderInterface
{
    /**
     * 指定されたリンクを含むインスタンスを返します。
     *
     * 指定されたリンクがすでに存在する場合、このメソッドはエラーなしで正常に戻る必要があります。 
     * $linkが既にコレクションにあるリンクオブジェクトと同一( ''==='' )な場合、リンクは存在します。
     *
     * @param LinkInterface $link
     *   このコレクションに含める必要のあるリンクオブジェクト。
     * @return static
     */
    public function withLink(LinkInterface $link);
 
    /**
     * 指定されたリンクが削除されたインスタンスを返します。
     *
     * 指定されたリンクが存在しない場合、このメソッドはエラーなしで正常に戻る必要があります。 
     * $linkが既にコレクションにあるリンクオブジェクトと同一( ''==='' )な場合、リンクは存在します。
     *
     * @param LinkInterface $link
     *   削除するリンク。
     * @return static
     */
    public function withoutLink(LinkInterface $link);
}