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

我正在尝试设计一个充分利用超媒体的RESTful服务.
优选地,用户代理应该只知道根URI,以便能够探索服务的所有功能 – 也就是说,我希望它在 maturity model中的第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"
}

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

一个fooRoot资源:

{
    // no properties,only links
    "_links" : { 
        "foos" : { "href" : "URI-to-foos" },"fooCreator" : { "href" : "URI-to-plain-fooWriter" }
    }
}

在foo资源中包含指向fooWriter的链接

foo资源:

{
    "category" : "category chosen from an enumeration of possible categories","aRelatedResource" : "resource identifier from chosen from a collection","_links" : {
        "self" : {...},"fooEditor" : { "href" : "URI-to-fooWriter-initialized-for-current-foo" }
    }
}

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" }
    }
}

总而言之,任何可以创建和编辑的资源都可能具有关联的编写器资源.
通过GET-ting编写器,用户代理可以以非常方便的方式创建/编辑资源.
嵌入在编写器中的有效负载被POST到其目的地,并且voilà:)

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

问题是……

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

一些参考:

> The Hypermedia scale
> Richardson Maturity Model
> A REST API leveraging the hypermedia quite well

解决方法

你描述的东西让我想起了 create and edit form link relations.但是,如果你正在构建一个API,它的使用是相当有限的,因为无论它是如何定义的,你都需要有人编程.

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

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

{
    "_links" : { 
        "plants" : { "href" : "/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"
          }
        ]
    }
}

要将新工厂添加到与防风草相关的集合中,POST到工厂收集资源并通过其链接与parnsip相关:

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

要随后修改胡萝卜,请对返回的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","related" : [ "/plants/parsnip" ]
}
----
HTTP/1.1 200 OK

上面的示例使用超文本应用程序语言(HAL)使用JSON传递“Level 3”REST语义. HAL简单而强大.我真正喜欢的一个约定是使用关系名称作为URI,当取消引用时,它直接指向关于该关系的文档以及它可以返回的资源.

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

相关文章

vue阻止冒泡事件 阻止点击事件的执行 <div @click=&a...
尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用...
后台我拿的数据是这样的格式: [ {id:1 , parentId: 0, name:...
JAVA下载文件防重复点击,防止多次下载请求,Cookie方式快速简...
Mip是什么意思以及作用有哪些