flask - JSONAPI : Update relationships including attributes

标签 flask json-api marshmallow flask-restless jsonapiframework

我的 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 规范?

最佳答案

使用 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 article 的属性id 1name 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到现有的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在实现之前。

关于flask - JSONAPI : Update relationships including attributes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50575752/

相关文章:

python - 错误 flask-sqlalchemy NameError : global name 'joinedload' is not defined

python - 如何在 Flask 中动态添加项目到 jinja 变量?

node.js - 使用 JSON API Serializer 创建更复杂的 JSON

python - 基于Flask的REST API : marshmallow vs flask-restful

python - 如何为 SQLAlchemy 模型动态生成棉花糖模式

python - Marshmallow Str() 不起作用,但 Function() 起作用

python - Bokeh 数据表未显示在 Flask 中

python - 使用 eventlet(异步)工作人员时出现错误 :grpc. _plugin_wrapping :AuthMetadataPluginCallback raised exception!(gunicorn)

php - Json API响应时间慢