JSONAPI:更新关系,包括属性

Posted

技术标签:

【中文标题】JSONAPI:更新关系,包括属性【英文标题】:JSONAPI: Update relationships including attributes 【发布时间】:2018-11-07 14:25:43 【问题描述】:

我的 SQLAlchemy 表中有一个嵌套对象,由 Marshmallow's nested schema feature 生成。例如,articles 对象 GET 响应将包含一个 authorUser 类型)对象。

我知道JSONAPI spec 已经允许更新关系。但是,通常我想在一次调用中更新一篇文章以及它的嵌套对象(包含新作者的文章的 POST 请求将自动创建作者)。是否可以发出包含尚不存在的关系对象资源的 PATCH 请求?

所以不只是这样:

PATCH /articles/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json


  "data": 
    "type": "articles",
    "id": "1",
    "relationships": 
      "author": 
        "data":  "type": "people", "id": "1" 
      
    
  

如果不存在作者,最好将其传入以创建新作者(这不是我的实际用例,但我有类似的现实生活需求):

PATCH /articles/1 HTTP/1.1
Content-Type: application/vnd.api+json
Accept: application/vnd.api+json

  "data": 
    "type": "articles",
    "id": "1",
    "relationships": 
      "author": 
        "data":  "type": "people", "id": "1", "attributes": "name": "new author":, "articles_written": 1 
      
    
  

这完全可能吗?或者对哪些 REST 框架可以支持这一点有建议,还是完全违反 JSON API 规范?

【问题讨论】:

【参考方案1】:

使用 JSON API 规范 v1.0 无法一次更新多个资源。但是有几个建议如何做到这一点。 official extensions 和 not supported anymore 都旨在支持一次创建、更新或删除多个请求。还有一个开放的拉取请求将introduce operations to upcoming JSON API spec v1.2。

例如,使用建议的操作[1] 一次更新两个资源的请求如下所示:

PATCH /bulk HTTP/1.1
Host: example.org
Content-Type: application/vnd.api+json


  "operations": [
    "op": "update",
    "ref": 
      "type": "articles",
      "id": "1"
    ,
    "data": 
      "type": "articles",
      "id": "1",
      "attributes": 
        "title": "Updated title of articles 1"
      
    
  , 
    "op": "update",
    "ref": 
      "type": "people",
      "id": "2"
    ,
    "data": 
      "type": "people",
      "id": "2",
      "attributes": 
        "name": "updated name of author 2"
      
    
  ]

这将在单个事务中更新 ID 为 1articletitle 属性和 ID 为 person 的资源的 name 属性 2

在单个事务中更新一对一关系和更新相关资源的请求如下所示:

PATCH /bulk HTTP/1.1
Host: example.org
Content-Type: application/vnd.api+json


  "operations": [
    "op": "update",
    "ref": 
      "type": "articles",
      "id": "1",
      "relationship": "author"
    ,
    "data": 
      "type": "people",
      "id": "2"
    
  , 
    "op": "update",
    "ref": 
      "type": "people",
      "id": "2"
    ,
    "data": 
      "type": "people",
      "id": "2",
      "attributes": 
        "name": "updated name of author 2"
      
    
  ]

这是一个请求,它创建一个新的person 并将其作为author 关联到一个现有的article,ID 为1

PATCH /bulk HTTP/1.1
Host: example.org
Content-Type: application/vnd.api+json


  "operations": [
    "op": "add",
    "ref": 
      "type": "people"
    ,
    "data": 
      "type": "people",
      "lid": "a",
      "attributes": 
        "name": "name of new person"
      
    
  , 
    "op": "update",
    "ref": 
      "type": "articles",
      "id": "1",
      "relationship": "author"
    ,
    "data": 
      "type": "people",
      "lid": "a"
    
  ]

请注意,顺序很重要。操作必须由服务器按顺序执行。因此,必须先创建资源,然后才能将其与现有资源相关联。为了表达关系,我们使用本地 id (lid)。

请注意,只有在必须以事务方式执行请求时才应使用操作。如果包含的每个操作都可以原子执行,则应使用单个请求。

据implementation list provided on jsonapi.org称,有一些库支持补丁扩展。

更新:操作未包含在 JSON API v1.1 的候选版本中。现在计划用于 v1.2。拉取请求的作者,也是规范的维护者之一,said 表示“操作现在是最高优先级”。包含操作的 v1.2 候选版本可能会在“1.1 最终版后几个月内发布 RC”。

[1] 目前仅建议将操作引入 JSON API v1.2,但未合并。可能会有重大变化。实施前请阅读related pull request。

【讨论】:

我需要的不是更新多个资源本身,而是修补嵌套资源。这是一个更详细的相关问题:***.com/q/50594051/1145905 除非我遗漏了什么,否则链接的官方扩展(jsonpatch 似乎更相关)似乎没有提供标准 PATCH 中关于更新 nested resources 我添加了一个示例请求,该请求使用为 JSON API v1.1 提出的操作。 感谢您的详细解释。太糟糕了,目前不支持。由于 flask-restless 还没有实现 [deprecated] 扩展和提议的操作,我看不出有一种方法可以按照你提议的方式来做我打算在这里做的事情。看来我得直接更新嵌套资源了

以上是关于JSONAPI:更新关系,包括属性的主要内容,如果未能解决你的问题,请参考以下文章

Ember数据:使用序列化和使用虚线jsonapi属性的attrs哈希来简化post对象

JSONAPI 实现

使用 JWT 和 JSONAPI 进行身份验证

具有存储到 firebase db 的实时更新的 JSON API

ExtJS 模型与 jsonapi 规范的关联

如何使用 Flask-rest-jsonapi / JSON API 在同一个 POST 方法中创建对象和相关对象?