用于创建和更新资源的超媒体友好型REST模式

tur*_*ula 8 rest design-patterns restful-architecture hypermedia web

我正在尝试设计一个充分利用超媒体的RESTful服务.
优选地,用户代理应该只知道根URI,以便能够探索服务的所有功能 - 也就是说,我希望它在成熟度模型中处于第3级.

现在,用户代理应该能够创建一些资源,并在以后编辑它们.在创建/编辑时,用户代理需要访问其他一些资源/枚举.

foo资源:

{
    "category" : "category chosen from an enumeration of possible categories",
    "color" : "color chosen from an enumeration of possible colors",
    "aRelatedResource" : "resource identifier from chosen from a collection"
}
Run Code Online (Sandbox Code Playgroud)

鉴于前面提到的要求,我提出了以下模式:

有一个fooRoot资源:

{
    // no properties, only links
    "_links" : { 
        "foos" : { "href" : "URI-to-foos" },
        "fooCreator" : { "href" : "URI-to-plain-fooWriter" }
    }
}
Run Code Online (Sandbox Code Playgroud)

包括链接fooWriterFOO资源:

foo资源:

{
    "category" : "category chosen from an enumeration of possible categories",
    "color" : "color chosen from an enumeration of possible colors",
    "aRelatedResource" : "resource identifier from chosen from a collection",
    "_links" : {
        "self" : {...},
        "fooEditor" : { "href" : "URI-to-fooWriter-initialized-for-current-foo" }
    }
}
Run Code Online (Sandbox Code Playgroud)

一个fooWriter将如下所示:

{
    "fooPayload" : {
        "category" : "NULL or pre-initialized",
        "color" : "NULL or pre-initialized",
        "aRelatedResource" : "NULL or pre-initialized"
    },
    "_links" : {
        "fooPayloadDestination" : { "href" : "URI-to-foos-or-foo" },
        "categoryEnum" : { "href" : "URI-to-categories" },
        "colorEnum" : { "href" : "URI-to-colors" },
        "availableResourcesToRelateWith" : { "href" : "some-other-URI" },
        ....
        .... and even something useful for pre-validation etc.
        "validator" : { href : "URI-to-some-resource-or-service" }
    }
}
Run Code Online (Sandbox Code Playgroud)

综上所述,可以创建和编辑的任何资源可以有关联的作家资源.
通过GET婷的作家,用户代理可以创建/在一个相当方便的方式编辑资源.嵌入在编写器中
有效负载会被POST到其目的地并且voilà:)

此外,应该有一个容器,其中包含指向资源及其编写器的新资源的链接(请参阅上面示例中的fooRoot).



问题是......

......上面描述的模式有一个众所周知的名字吗?
...有没有更好的方法来解决创建/编辑问题,在创建/编辑时需要相邻资源,第3级成熟度仍然"保持"?

一些参考:

Jon*_*n W 1

你所描述的让我想起了一些创建和编辑表单链接关系的事情。然而,如果您正在构建一个 API,那么它的用途相当有限,因为无论它是如何定义的,您都需要有人对其进行编程。

在我看来,组织上面给出的示例的最简单方法是定义一个根菜单,如下所示:

GET / HTTP/1.1
Accept: application/hal+json
----
HTTP/1.1 200 OK
Content-Type:application/hal+json

{
    "_links" : { 
        "plants" : { "href" : "/plants" }
    }
}
Run Code Online (Sandbox Code Playgroud)

plants关系将保存由给定媒体类型定义的植物资源集合(假设它是application/vnd.biology-example-org.plant):

GET /plants HTTP/1.1
Accept: application/hal+json
----
HTTP/1.1 200 OK
Content-Type:application/hal+json

{
    "_links" : { 
        "self" : { "href" : "/plants" },
        "plant": [
          {
            "href" : "/plants/parsnip",
            "title" : "The Parsnip",
            "type" : "application/vnd.biology-example-org.plant+json"
          }
        ]
    }
}
Run Code Online (Sandbox Code Playgroud)

要将新植物添加到与防风草相关的集合中,请发布到plants集合资源并通过其链接与防风草相关:

POST /plants HTTP/1.1
Content-Type: application/vnd.biology-example-org.plant+json

{
    "title" : "The Carrot - a cousin of the Parsnip",
    "category" : "vegetable",
    "color" : "orange",
    "related" : [ "/plants/parsnip" ]
}
----
HTTP/1.1 201 Created
Location: http://biology.example.org/plants/carrot
Run Code Online (Sandbox Code Playgroud)

要随后修改胡萝卜,请向返回的 URL 发出 PUT:

PUT /plants/carrot HTTP/1.1
Content-Type: application/vnd.biology-example-org.plant+json

{
    "title" : "The Carrot - the orange cousin of the Parsnip",
    "category" : "vegetable",
    "color" : "orange",
    "related" : [ "/plants/parsnip" ]
}
----
HTTP/1.1 200 OK
Run Code Online (Sandbox Code Playgroud)

上面的示例使用超文本应用程序语言 (HAL) 通过 JSON 来传达“3 级”REST 语义。HAL 简单但功能非常强大。我真正喜欢的约定之一是使用关系名称作为URI,当取消引用时,它直接指向有关该关系及其可以返回的资源的文档。

如果您想使用这样的实时 API,我强烈建议您查看HALtalk,它是 HAL 的实时演示 API。