【问题标题】:Does Restful Design support bulkcreate?Restful Design 是否支持批量创建?
【发布时间】:2016-01-26 18:49:16
【问题描述】:

我有一个 API 可以让用户添加一本书 http://127.0.0.1/book
如果用户想一次创建 100 本书怎么办?

我找了一些讨论here
LiorH说:

Although bulk operations (e.g. batch create) are essential in many systems,  
they are not formally addressed by the RESTful architecture style.

这是一个宁静的设计建议吗?

我喜欢一次发布一个项目
但是我的搭档想要一次创建所有内容
我认为如果其中一些格式有效,而另一些格式无效,则一次全部创建会有问题
我想确保这一点

【问题讨论】:

    标签: rest restful-architecture


    【解决方案1】:

    我喜欢Thierry Templier 的方法,如文章Implementing Bulk Updates within RESTful Services 中所述。我将在这里总结主要思想,并根据您的上下文进行调整。不过,我确实建议阅读全文

    请求

    通常,POST 方法用于将单个元素添加到集合中。所以,我们可以有一个资源,它的方法同时接受单个元素和元素集合。根据输入的有效负载,该处理检测是否必须进行单个或批量添加。

    事实上,在资源路径中使用另一个资源,例如 /books/bulk,并不是真正的 RESTful,因此它不是正确的方法。

    当创建单个元素时,我们可以有这样的东西:

    POST /books
    Content-Type: application/json
    {
        "title": "The Lord of the Rings - The Fellowship of the Ring",
        "author": "J. R. R. Tolkien",
        (...)
    }
    

    以及以下,在批量操作的情况下:

    POST /books
    Content-Type: application/json
    [
        {
            "title": "The Lord of the Rings - The Fellowship of the Ring",
            "author": "J. R. R. Tolkien",
            (...)
        },
        {
            "title": "The Lord of the Rings - The Two Towers",
            "author": "J. R. R. Tolkien",
            (...)
        },
        (...)
    ]
    

    响应

    创建单个元素时,响应非常简单,通常包含两件事:

    • 状态码201(已创建)
    • 标头 Location 包含新创建元素的 URL
    201 Created
    Location: http://example.com/api/book/{id}
    

    Location 标头接受一个值,并且可以在响应中定义一次。 也就是说,由于 POST 方法的语义取决于 RESTful 服务设计者,我们可以利用标头 Link 来提供此提示,如下所述:

    201 Created
    Link: <http://example.com/api/book/{id}>, <http://example.com/api/book/{id}>
    

    交易

    在批量操作中,您可以考虑使用事务方法:

    • 一切正常,所有数据都已插入
    • 至少有一个元素存在验证错误且未添加任何内容
    • 一个或多个插入失败,所有内容都回滚
    422 Unprocessable Entity
    Content-type: application/json
    [
        {
            "index": 1,
            "messages": [
                {
                    "title": "The title should at least have three characters."
                 }
            ]
        },
        {
            "index": 1,
            "messages": [
                {
                    "id": "The value of the field it isn't unique."
                 }
            ]
        },
    ]
    

    在插入错误的情况下:

    500 Internal Server Error
    Content-type: application/json
    [
        {
            "index": 1,
            "messages": [
                "The book can't be added because of the error #22 (description)"
            ]
        },
        (...)
    ]
    

    对于非事务处理,响应的状态码将始终为200,并且响应负载中描述了错误(如果有),如下所示:

    200 OK
    Content-type: application/json
    [
        {
            "index": 1,
            "status": "error",
            "messages": [
                "The book can't be added because of the error #22 (description)"
            ]
        },
        {
            "index": 2,
            "status": "success",
            "auto-generated-id": "43"
        },
        (...)
    ]
    

    【讨论】:

      【解决方案2】:

      REST 谈论交换您关心的事物的表示。如果您关心书籍集,请为此创建一个表示并允许客户POST 他们。

      这些服务中最棘手的部分始终是响应,因为通常的模式是在POST 资源之后,您的响应是或重定向到新创建的资源的 URI。

      但是,没有什么可以阻止您使用 URI 列表进行响应,这意味着 POST 一组书的结果是一组已创建的资源。

      但是,这里有一个很大的警告,那就是失败语义。如果只有一些书被创造出来,会发生什么?是否有可能只创建一些书籍,然后客户必须处理它?这是事情变得相当棘手的地方,这就是很多人试图避免这种情况的原因。它从根本上没有什么问题,但它使 API 变得相当复杂,而且性能提升可能比人们想象的要小。

      您不能一次制作一本书有什么原因吗?我建议让 API 尽可能简单,除非你有令人信服的理由让它变得更复杂。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-04
        • 1970-01-01
        • 2021-11-29
        • 2021-12-03
        • 2020-07-15
        • 1970-01-01
        相关资源
        最近更新 更多