RESTAPI:在给定详细表示的情况下创建关联资源是否合理?

RESTAPI:在给定详细表示的情况下创建关联资源是否合理?,api,rest,api-design,Api,Rest,Api Design,假设我们有几个收集资源 我可以在此集合上创建实例资源: POST /people { "_links" : { "car" : { "href" : "/cars/66H8800" } } "name": "John" } 然而,接受以下情况是否合理 POST /people { "_links" : { "car" : { "license" : "66H8800"

假设我们有几个收集资源

我可以在此集合上创建实例资源:

POST /people
{
    "_links" : {
        "car" : {
            "href" : "/cars/66H8800"
        }
    }
    "name": "John"
}
然而,接受以下情况是否合理

POST /people
{
    "_links" : {
        "car" : {
            "license" : "66H8800"
        }
    }
    "name": "John"
}
…如果
/cars/66G8800
还不存在,这将导致创建资源
/people/1
(例如)和
/cars/66G8800


似乎我开始把
POST
(创建新资源)和
PUT
(更新/创建特定资源)的目的混为一谈了。

执行摘要:两者都可以。我同意1,但要注意的是,你至少需要两次,可能是三次请求。一个人把车放好,接着另一个人把车主/司机的名字写下来。如果您事先没有汽车的完整资源数据,请在PUT之前执行GET,必要时更新PUT请求正文。如果GET返回404,那么只需将PUT中的未知字段留空,并定义服务器将用默认值填充它们(而不是拒绝PUT请求)

长答覆:

REST不指定消息正文的格式。
REST对您造成的唯一限制是:

  • 统一接口,在本例中是HTTP的
    POST
    方法。使用POST意味着您打算将请求主体定义的新资源附加到目标URI标识的集合中。如果这样做需要服务器也必须在其他地方创建资源,那么就这样做吧
  • 一种有记录的,最好是通用的媒体类型。使用现有媒体类型(例如)或记录您创建的媒体类型
  • 使用超媒体(即链接)提升应用程序状态(浏览器窗口)。在请求主体中,您可以发送任何您喜欢的内容。服务器负责在其响应中提供车和人之间的超链接
  • 请求必须是自包含的。这意味着您不能发送一个请求“将当前车辆设置为66H8800”,然后发送第二个请求“为当前设置的车辆创建驾驶员”。这样做需要在请求之间记住服务器状态,这在REST中是被禁止的(因为它破坏了许多事情,比如负载平衡)。看起来您没有这样做,但我无法从提供的代码中判断

  • 您的媒体类型决定是否应该存在“许可证”密钥。选择或创建一个您认为合适的答案。

    我仍在研究您的答案,以了解原则。至于“两者都可以”,在这种情况下,使用#2以消除客户端对任何检查逻辑的需要是否有意义?是的,如果需要的话。但在这种情况下,我不会使用“_links”作为不包含链接的属性的名称;-)如果您希望格式是RESTful的,请确保记录格式#1与HAL非常接近,因此创建一个几乎相同的自定义格式并对其进行描述所需的工作量远小于解析链接所需的工作量,并且对未来的通用性也较差。请阅读,特别是最后一点,“RESTAPI应该[使用]一组标准化的媒体类型”。应该,而不是必须。