我有一个可能包含大量资源的端点。它们以分页列表的形式返回。每个资源都有一个唯一的id、一个rank字段和一些其他数据。
从语义上讲,资源是按照它们的rank排序的。用户应该能够更改该顺序。我正在寻找一个restful接口来更改大型集合中许多资源中的rank字段。
重新排序一个资源可能会导致许多资源的rank字段发生更改。例如,考虑将最不重要的资源移到最重要的位置。许多资源可能需要“降级”。
对集合进行分页使问题变得更加棘手。以前有一个小收藏
rank字段是整数类型。如果能得到一个合理的接口,我可以改变它的类型。
例如:
GET /my-resources?limit=3&marker=234返回:

{
  "pagination": {
    "prevMarker": 123,
    "nextMarker": 345
  },
  "data": [
    {
      "id": 12,
      "rank": 2,
      "otherData": {}
    },
    {
      "id": 35,
      "rank": 0,
      "otherData": {}
    },
    {
      "id": 67,
      "rank": 1,
      "otherData": {}
    }
  ]
}

深思熟虑的方法。
1)列表的修补程序请求。
我们可以用标准的json补丁请求修改rank字段。例如:
[
  {
    "op": "replace",
    "path": "/data/0/rank",
    "value": 0
  },
  {
    "op": "replace",
    "path": "/data/1/rank",
    "value": 1
  },
  {
    "op": "replace",
    "path": "/data/2/rank",
    "value": 2
  }
]

我看到这种方法存在的问题:
a)在修补操作中使用path中的数组索引。每个资源都有一个唯一的ID。我宁愿使用它。
b)我不确定分页集合中的数组索引应该引用什么?我想它应该在所有页面都被接收并背靠背合并后引用全局索引。
c)集合中资源的索引可以由其他客户端更改。当前客户在索引1处的想法可能不再在该索引处。我想可以先在补丁请求中添加测试操作。所以完整的补丁请求如下所示:
[
  {
    "op": "test",
    "path": "/data/0/id",
    "value": 12
  },
  {
    "op": "test",
    "path": "/data/1/id",
    "value": 35
  },
  {
    "op": "test",
    "path": "/data/2/id",
    "value": 67
  },
  {
    "op": "replace",
    "path": "/data/0/rank",
    "value": 0
  },
  {
    "op": "replace",
    "path": "/data/1/rank",
    "value": 1
  },
  {
    "op": "replace",
    "path": "/data/2/rank",
    "value": 2
  }
]

2)将集合设为“dictionary/json对象,并对字典使用补丁请求。
与1)相比,这种方法的优点是我们可以在修补操作中使用path中的唯一id。
返回资源中的“数据”不再是列表:
{
  "pagination": {
    "prevMarker": 123,
    "nextMarker": 345
  },
  "data": {
    "12": {
      "id": 12,
      "rank": 2,
      "otherData": {}
    },
    "35": {
      "id": 35,
      "rank": 0,
      "otherData": {}
    },
    "67": {
      "id": 67,
      "rank": 1,
      "otherData": {}
    }
  }
}

然后我可以在补丁操作中使用唯一的id。例如:
{
    "op": "replace",
    "path": "/data/12/rank",
    "value": 0
  }

我看到这种方法存在的问题:
a)我的资源集合可能很大,我很难理解分页json对象或分页字典的含义。我不确定是否可以在这个大对象上定义迭代顺序。
3)有一个单独的端点,用于使用PUT修改列组
我们可以添加一个像这样的新端点。
并期望在put请求中传递有序id的完整列表。例如
[
  {
    "id": 12
  },
  {
    "id": 35
  },
  {
    "id": 67
  }
]

我们将使PUT /my-resource-ranks成为只读字段,因此不能通过其他端点对其进行修改。
我看到这种方法存在的问题:
a)需要发送完整的订购清单。在MyResource.rank的put请求中,我们将不包括任何其他数据,而只包括资源的唯一id。它比发送完整的资源不那么严重,但是完整的有序列表仍然可以很大。
4)避免/my-resource-ranks字段和“rank”是/my collections响应中的顺序。
返回的资源中不会有“rank”字段,并且它们已经在响应中根据其排名进行排序。
{
  "pagination": {
    "prevMarker": 123,
    "nextMarker": 345
  },
  "data": [
    {
      "id": 35,
      "otherData": {}
    },
    {
      "id": 67,
      "otherData": {}
    },
    {
      "id": 12,
      "otherData": {}
    }
  ]
}

用户可以使用json补丁中的similar question操作更改顺序。
[
  {
    "op": "test",
    "path": "/data/2/id",
    "value": 12
  },
  {
    "op": "move",
    "from": "/data/2",
    "path": "/data/0"
  }
]

我看到这种方法存在的问题:
a)从客户的角度来看,我希望服务器可以自由地以“任意”顺序返回MyResource.rank。只要顺序一致,“简单”服务器实现的最佳顺序可能不同于应用程序定义的秩。
b)与1)b)相同。修补程序操作中的索引是否在接收到所有页并将其背靠背合并后引用全局索引?还是指当前页中的索引?
更新:
有人知道来自现有公共API的其他例子吗?寻找更多的灵感。到目前为止我有:
move
Spotify's Reorder a Playlist's Tracks

最佳答案

我会的
使用修补程序
定义专门用于更新订单的专用内容类型。
application/patch+json类型非常适合直接修改,但我认为您的用例足够独特,足以保证一个有用的、最小的专用内容类型。

09-10 09:56
查看更多