# APILetter S1E5 如何设计一个符合 RESTFul 风格的批量操作的 OpenAPI 接口？

- Link: https://www.ixiqin.com/2023/07/03/apiletter-s1e5-how-to-design-a-batch-operation-openapi-interface-conforms-to-the-restful-style/
- Published: 2023-07-03T10:35:41+08:00
- Author: 白宦成

文章目录

 [Toggle](https://www.ixiqin.com/2023/07/03/apiletter-s1e5-how-to-design-a-batch-operation-openapi-interface-conforms-to-the-restful-style/#)

    - [批量创建、批量更新、批量删除](https://www.ixiqin.com/2023/07/03/apiletter-s1e5-how-to-design-a-batch-operation-openapi-interface-conforms-to-the-restful-style/#%e6%89%b9%e9%87%8f%e5%88%9b%e5%bb%ba%e3%80%81%e6%89%b9%e9%87%8f%e6%9b%b4%e6%96%b0%e3%80%81%e6%89%b9%e9%87%8f%e5%88%a0%e9%99%a4)
       * [批量创建](https://www.ixiqin.com/2023/07/03/apiletter-s1e5-how-to-design-a-batch-operation-openapi-interface-conforms-to-the-restful-style/#%e6%89%b9%e9%87%8f%e5%88%9b%e5%bb%ba)
       * [批量更新用户](https://www.ixiqin.com/2023/07/03/apiletter-s1e5-how-to-design-a-batch-operation-openapi-interface-conforms-to-the-restful-style/#%e6%89%b9%e9%87%8f%e6%9b%b4%e6%96%b0%e7%94%a8%e6%88%b7)
       * [批量删除](https://www.ixiqin.com/2023/07/03/apiletter-s1e5-how-to-design-a-batch-operation-openapi-interface-conforms-to-the-restful-style/#%e6%89%b9%e9%87%8f%e5%88%a0%e9%99%a4)
 * [总结](https://www.ixiqin.com/2023/07/03/apiletter-s1e5-how-to-design-a-batch-operation-openapi-interface-conforms-to-the-restful-style/#%e6%80%bb%e7%bb%93)

### 批量创建、批量更新、批量删除

批量获取说完了，接下来我们来聊聊批量更新，实际上批量更新、批量创建虽然有场景，但
也不多，在这种场景下，我们已经很难像批量获取那样，在原有资源上进行操作，而是需要
借助批量资源来实现批量操作。

以用户资源（User）为例，当我们需要对其进行批量创建、删除、更新时，我们需要创建一个
批量资源 BulkUser，并通过对 BulkUser 操作，来创建用户。Bulk User 本质上是将请求的
多个资源转换为了异步的任务，在发起后，开发者可以在任务结果中查询具体的值来使用。

> 如何理解异步的任务？
> 这里异步的任务更多是一种设计表现，并不强制要求一定异步。异步
> 的表现设计和相关的接口实现，是为了给后续留出纵向扩展的空间。既 无论是否行为是否
> 真实异步，都需要在返回结果中返回任务 ID & 任务状态，以便于开发者自行实现异步处理
> 的逻辑。

    ```javascript
    {
        "code":0,
        "data":{
           "job":{          "id":"123",          "status":"ok"        },
            "results":[
                {
                ...
                }
            ]
        }
    }
    Code language: JavaScript (javascript)
    ```

#### 批量创建

批量创建用户的操作和创建单个用户的操作是比较接近的，主要差异点在于 Path 上有区别，
且传递参数时，会传递多个资源的属性。

批量创建用户

    ```php
    # request
    POST /bulk_users/

    {
        "users":[
            {
                // user1
                ...
            },
            {
                // user2
                ...
            }
        ]
    }
    # response
    HTTP/1.1 200 OK
    {
        "code":0,
        "data":[
           {
                // user1
                ...
            },
            {
                // user2
                ...
            }
        ]
    }
    Code language: PHP (php)
    ```

#### 批量更新用户

批量更新时，你已经知道了你需要更新的资源的 ID，因此，可以这样设计的你的接口：

    ```php
    #request
    PUT /bulk_users?id[]=1&id[]=2

    {
        "gender":"other"
    }

    # response
    HTTP/1.1 204 No Content
    {
     "code":0,
        "data":[
           {
                // id=1
                ...
            },
            {
                // id=2
                ...
            }
        ]
    }
    Code language: PHP (php)
    ```

#### 批量删除

有了上面的几个例子，批量删除就比较好定义了。就像这样：

    ```php
    #request
    DELETE /bulk_users?id[]=1&id[]=2

    # response
    HTTP/1.1 200 OK
    {
     "code":0,
        "data":[
           {
                // id=1
               "status":"deleted"
            },
            {
                // id=2
                "status":"deleted"
            }
        ]
    }
    Code language: PHP (php)
    ```

## 总结

批量操作在获取场景，可以考虑通过 List + Filter 的方式，或搜索的方式来实现一套更加
标准的搜索接口，而规避提供定制化的自定义接口。从规范的视角，两者都是符合规范的，
也可以都对用户提供，并不互斥。而对于没办法复用的创建、更新、删除，则可以考虑使用
创建异步任务的方式，来实现批量操作，给开发者一个明确的异步预期，让开发者可以自行
查询业务的实现方式。
