API设计:查询子资源

时间:2018-07-09 14:40:04

标签: rest api-design

我们有一个可以建模为嵌套对象的资源

GET /A/
[
  {
    "name": "my_a",
    "B": [
      {"name": "my_b", "address": "0xbeef"}
    ]  
  }
]

或子资源,例如

GET /A/my_a/B
[
  {
    "name":"my_b", "address": "0xbeef"
  }
]

我们的客户想要一种基于类型B的属性来查询类型A的对象的方法,例如“给我所有具有名称为“ my_b”的B对象的A对象。”

使用“ B作为子资源”的书写方式来编写API似乎更可取,因为如果有许多B对象类型,它就很容易分页。此外,检索B对象可能会很昂贵,因此,如果仅某些客户端对B感兴趣,则需要单独调用以检索子资源B是有意义的。但是,如果子对象B允许用户查询子资源,这似乎也很奇怪。资源不会返回到结果中。

例如,查询形式很自然:

GET /A?query=B.address[equals]0xbeef
[
  {
    "name": "my_a",
    "B": [
      {"name": "my_b", "address": "0xbeef"}
    ]  
  }
]

但是查询看起来不那么

GET /A?query=B.address[equals]0xbeef
[
  {
    "name": "my_a"
  }
]

我正在考虑的一种折衷方案是使用嵌套方法,但默认情况下不包括B对象。查询参数可以暴露B。因此

GET /A?query=B.address[equals]0xbeef&include_b=true
[
  {
    "name": "my_a",
    "B": [
      {"name": "my_b", "address": "0xbeef"}
    ]  
  }
]

我研究了“ REST,嵌套对象,查询”并找到了示例。这些示例大多数都将子资源包含为嵌套对象,include_b参数似乎是我的设计所独有的。

因此,我正在寻找有关此方法的一般反馈,并查看这是否是已知解决方案的常见问题。很好奇听到回来了。

编辑1: 更新了示例,以显示查询可以针对任意属性。

1 个答案:

答案 0 :(得分:0)

正如@RomanVottner指出的那样,我实际上不是在设计RESTful API。相反,API更接近于已转换为使用HTTP / JSON的RPC。实际上,我的团队遵循Google API Design guide,它本身就是在指示如何编写GRPC API,然后(我认为)它们会自动翻译为Web端点。

因此,最终,除了得知我的问题不准确之外,我还没有回答我的风格问题。我很可能会使用我在问题中提出的解决方案。