2

我的 SQLAlchemy 表中有一个嵌套对象,由Marshmallow 的嵌套模式特性生成。例如,一个articles对象 GET 响应将包括一个authorUser类型)对象。

我知道JSONAPI 规范已经允许更新关系。但是,通常我想在一次调用中更新一篇文章以及它的嵌套对象(包含新作者的文章的 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 规范?

4

1 回答 1

2

使用 JSON API 规范 v1.0 一次更新多个资源是不可能的。但是有几个建议如何做到这一点。不再支持的两个官方扩展旨在支持一次创建、更新或删除多个请求。还有一个开放的拉取请求,它将向即将到来的 JSON API 规范 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的title属性和具有id的资源的属性。article1nameperson2

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

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)。

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

根据jsonapi.org 上提供的实现列表,有一些库支持补丁扩展。

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

[1] 目前仅建议但未合并向 JSON API v1.2 引入操作。可能会有重大变化。在实施之前阅读相关的拉取请求

于 2018-05-30T22:13:10.097 回答