翻译进度
10
分块数量
3
参与人数

PSR-13 超媒体链接

这是一篇协同翻译的文章,你可以点击『我来翻译』按钮来参与翻译。

超媒体链接

HTML 和各种 API 格式的上下文中,超媒体链接已经变成 Web 越来越重要的一部分。然而遗憾的是,没有一种通用单一的超媒体格式,也没有一种通用的方式来表示链接间的格式。

这个规范的目标是提供 PHP 开发者一个简单的,通用的一个表示超媒体连接独立序列化格式被使用的方式。这也允许一个系统将用超媒体链接去序列化的一个响应,并将其转换为一个或更多独立决定处理这些链接,即链接应该是什么的有线格式。

为了避免歧义,文档大量使用了「能愿动词」,对应的解释如下:

  • 必须 (MUST):绝对,严格遵循,请照做,无条件遵守。
  • 一定不可 (MUST NOT):禁令,严令禁止。
  • 应该 (SHOULD) :强烈建议这样做,但是不强求。
  • 不该 (SHOULD NOT):强烈不建议这样做,但是不强求。
  • 可以 (MAY) 和可选 (OPTIONAL) :选择性高一点,在这个文档内,此词语使用较少。

 参见 RFC 2119

参考文献

imajinyun 翻译于 3周前

1. 规范

1.1 基本链接

一个超媒体链接至少是由这些组成的:

  • 一个 URI 表示目标资源被引用。
  • 一个关系定义如何把目标资源与源联系起来。

链接的各种其他属性可能存在,具体取决于所使用的格式。作为额外的属性将不能标准化和通用,故本规范不寻求规范他们。

就本规范而言,下列定义是适用的:

  • Implementing Object - 通过这个规范一个对象实现一个接口的定义。
  • Serializer - 一个库或者其它系统需要一个或多个 Link 对象,并用它定义的一些格式产生一个序列化的表示。
imajinyun 翻译于 3周前

1.2 属性

所有的链接 可以 包含零个或者多个 URI 和关系之外的附加属性。没有正式的在这里允许的能注册的值和值的有效性取决于上下文,并且通常取决于一个特定的序列化格式。一般情况下支持的值包括 hreflangtitletype

如果序列化格式需要,序列化 可以 忽略链接对象上的属性。不管怎样,序列化 应该 对所有提供的属性尽可能地进行编码,以便允许用户扩展,除非有通过序列化格式的定义去阻止的情况。

一些属性(一般为 hreflang)在他们的上下文中 可以 多次出现。因此,一个属性值 可以 是一个数组形式的值而不是一个简单的值。序列化 可以 对任何适合于序列化格式的格式对该数组进行编码(比如:一个空格分隔的列表,逗号分隔的列表等等)。如果在一个特定的上下文中,指定的一个属性不允许有多个值,序列化 必须 使用第一个提供的值而忽略所有后续的值。

如果一个属性的值为布尔值 true,则序列化 可以 使用序列化格式支持的和合适的缩写形式。例如:当属性的存在有布尔意义时,HTML 允许属性没有值。当且仅当该属性为布尔值 true 时,这个规则才适用,而不适用于 PHP 中的其他任何 truthy 值,例如整数 1

如果一个属性的值为布尔值 false,序列化 应该 完全省略属性,除非这样做会改变结果的语义含义。当且仅当该属性为布尔值 false 时,这个规则才适用,而不适用于 PHP 中的其他任何 falsey 值,例如整数 0

imajinyun 翻译于 3周前

1.3 关系

链接关系定义为字符串,在公开定义关系的情况下为一个简单关键字,或者在私有关系的情况下为一个绝对 URI

在使用一个简单的关键字的情况下,它 应该IANA 注册表中的一个匹配:

http://www.iana.org/assignments/link-relations/link-relations.xhtml

可以 选择使用 microformats.org 注册表,但这可能不适用于任何情况:

http://microformats.org/wiki/existing-rel-values

一个未在上述其中一个注册表或者一个类似的公共注册表中定义的关系被视为 private,也就是说,明确到一个特定的应用和使用场景。例如:关系必须使用一个绝对 URI 的情形。

imajinyun 翻译于 3周前

1.4 链接模板

RFC 6570 为 URI 模板定义了一种格式,也就是说,URI 这种模式期望通过客户端工具提供的值去填充。有些超媒体格式支持模板链接而有些则不支持,并且可能有一种特殊的方式来表示链接是一个模板。一个不支持 URI 模板格式化程序 必须 忽略它遇到的任何模板的链接。

1.5 可演进的提供者

在某些情况下,一个链接提供者可能需要添加其他链接的能力。在其他情况下,链接提供者必须是只读的,其中链接在运行时从其他某个数据源衍生。出于这个原因,可修改的提供者可以可选地实现辅助的接口。

另外,一些链接提供者对象,如 PSR-7 响应对象,被设计为不可变的。这意味着在就地添加链接的方法将是不兼容的。因此,EvolvableLinkProviderInterface 类的单一方法需要返回一个新的对象,与原始对象相同,但要包含一个额外的链接对象。

imajinyun 翻译于 2周前

1.6 可演进的链接对象

链接对象在大部分情况下是值对象。因此,允许它们去演进,与 PSR-7 值对象一样是个有用的选项。为了这个缘故,一个额外的 EvolvableLinkInterface 类被包含进来,它提供了只需一次更改而生成新对象实例的方法。相同的模式被使用在 PSR-7 中,归功于 PHPcopy-on-write 机制,使 CPU 和内存依然高效。

然而,模板没有可演进的方法,由于一个链接的模板值是基于专门的 href 值。它被 禁止 独立地设置,但衍生自 href 值是否为 RFC 6570 的链接模板。

2. 包

描述的接口和类作为 psr/link 包的一部分被提供。

imajinyun 翻译于 2周前

3. 接口

3.1 Psr\Link\LinkInterface

<?php

namespace Psr\Link;

/**
 * 一个可读的链接对象。
 */
interface LinkInterface
{
    /**
     * 返回链接的目标。
     *
     * 目标链接必须是以下中的一个:
     * 
     * - 一个绝对的 URI,由 RFC 5988 定义的。
     * - 一个相对 URI,由 RFC 5988 定义的。相对链接的基础
     *   被假定为基于客户端的上下文而已知。
     * - 一个由 RFC 6570 定义的 URI 模板。
     *
     * 如果返回一个 URI 模板,isTemplated 必须返回 True。
     *
     * @return string
     */
    public function getHref();

    /**
     * 返回的是否为一个模板链接。
     *
     * @return bool
     *   True 表示链接对象是模板, False 相反。
     */
    public function isTemplated();

    /**
     * 返回链接的关系类型。
     *
     * 此方法返回一个链接的 0 个或更多关系类型,返回值为
     * 字符串数组。
     *
     * @return string[]
     */
    public function getRels();

    /**
         * 返回描述目标 URI 的一个属性列表。
     *
     * @return array
     *  属性的一个键值对列表,其中键是一个字符串,值要么是一个 PHP 原生提供的,要么是 PHP 字符串数组。如果没有值,必须返回一个空的数组。
     */
    public function getAttributes();
}
imajinyun 翻译于 1周前

3.2 Psr\Link\EvolvableLinkInterface

<?php

namespace Psr\Link;

/**
 * An evolvable link value object.
 */
interface EvolvableLinkInterface extends LinkInterface
{
    /**
     * Returns an instance with the specified href.
     *
     * @param string $href
     *   The href value to include.  It must be one of:
     *     - An absolute URI, as defined by RFC 5988.
     *     - A relative URI, as defined by RFC 5988. The base of the relative link
     *       is assumed to be known based on context by the client.
     *     - A URI template as defined by RFC 6570.
     *     - An object implementing __toString() that produces one of the above
     *       values.
     *
     * An implementing library SHOULD evaluate a passed object to a string
     * immediately rather than waiting for it to be returned later.
     *
     * @return static
     */
    public function withHref($href);

    /**
     * Returns an instance with the specified relationship included.
     *
     * If the specified rel is already present, this method MUST return
     * normally without errors, but without adding the rel a second time.
     *
     * @param string $rel
     *   The relationship value to add.
     * @return static
     */
    public function withRel($rel);

    /**
     * Returns an instance with the specified relationship excluded.
     *
     * If the specified rel is already not present, this method MUST return
     * normally without errors.
     *
     * @param string $rel
     *   The relationship value to exclude.
     * @return static
     */
    public function withoutRel($rel);

    /**
     * Returns an instance with the specified attribute added.
     *
     * If the specified attribute is already present, it will be overwritten
     * with the new value.
     *
     * @param string $attribute
     *   The attribute to include.
     * @param string $value
     *   The value of the attribute to set.
     * @return static
     */
    public function withAttribute($attribute, $value);

    /**
     * Returns an instance with the specified attribute excluded.
     *
     * If the specified attribute is not present, this method MUST return
     * normally without errors.
     *
     * @param string $attribute
     *   The attribute to remove.
     * @return static
     */
    public function withoutAttribute($attribute);
}

3.2 Psr\Link\LinkProviderInterface

<?php

namespace Psr\Link;

/**
 * A link provider object.
 */
interface LinkProviderInterface
{
    /**
     * Returns an iterable of LinkInterface objects.
     *
     * The iterable may be an array or any PHP \Traversable object. If no links
     * are available, an empty array or \Traversable MUST be returned.
     *
     * @return LinkInterface[]|\Traversable
     */
    public function getLinks();

    /**
     * Returns an iterable of LinkInterface objects that have a specific relationship.
     *
     * The iterable may be an array or any PHP \Traversable object. If no links
     * with that relationship are available, an empty array or \Traversable MUST be returned.
     *
     * @return LinkInterface[]|\Traversable
     */
    public function getLinksByRel($rel);
}

3.3 Psr\Link\EvolvableLinkProviderInterface

<?php

namespace Psr\Link;

/**
 * An evolvable link provider value object.
 */
interface EvolvableLinkProviderInterface extends LinkProviderInterface
{
    /**
     * Returns an instance with the specified link included.
     *
     * If the specified link is already present, this method MUST return normally
     * without errors. The link is present if $link is === identical to a link
     * object already in the collection.
     *
     * @param LinkInterface $link
     *   A link object that should be included in this collection.
     * @return static
     */
    public function withLink(LinkInterface $link);

    /**
     * Returns an instance with the specifed link removed.
     *
     * If the specified link is not present, this method MUST return normally
     * without errors. The link is present if $link is === identical to a link
     * object already in the collection.
     *
     * @param LinkInterface $link
     *   The link to remove.
     * @return static
     */
    public function withoutLink(LinkInterface $link);
}

本文章首发在 Laravel China 社区
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。

参与译者:3
讨论数量: 0
发起讨论


暂无话题~