我的SQLAlchemy表中有一个嵌套对象,使用Marshmallow's nested schema feature生成。例如,articles
对象GET响应将包含author
(一个User
类型)对象。
我知道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规范?
答案 0 :(得分:2)
使用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"
}
}
}]
}
这将在单个事务中更新title
的{{1}} article
属性1
以及name
资源person
资源,其ID为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
关联到ID为article
的现有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,有一些库支持Patch扩展。
更新:操作未包含在JSON API v1.1的候选发布版中。它现在计划在v1.2。 pull请求的作者,也是规范的维护者之一,said“操作现在是最高优先级”。包含操作的v1.2的候选版本可能会在1.1最终版本的几个月内发布。“
[1]目前只建议向JSON API v1.2引入操作但不合并。可能会有重大变化。在实施之前阅读related pull request。