API设计:查询子资源
API Design: Querying a sub-resource
我们有一个可以建模为嵌套对象的资源
GET /A/
[
{
"name": "my_a",
"B": [
{"name": "my_b", "address": "0xbeef"}
]
}
]
或子资源,如
GET /A/my_a/B
[
{
"name":"my_b", "address": "0xbeef"
}
]
我们的客户想要一种方法来根据类型 B 的属性查询类型 A 的对象,例如"get me all the A objects who have B objects with name 'my_b'".
使用"B as a sub-resource" 的写作风格来编写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, nested objects, querying" 并找到了示例。这些示例中的大多数都将子资源作为嵌套对象包含在内,include_b
参数似乎是我的设计所特有的。
所以,所以,我正在寻找关于这种方法的一般反馈,看看这是否是已知解决方案的常见问题。很想知道返回的内容。
编辑 1:
更新了示例以显示查询可以针对任意属性。
正如@RomanVottner 所指出的,我实际上并不是在设计 RESTful API。相反,API 更接近于转换为使用 HTTP/JSON 的 RPC。事实上,我的团队遵循 Google API Design guide,它本身决定了如何编写 GRPC API,然后(我假设)自动将其转换为 Web 端点。
所以,在一天结束的时候,除了得知我的问题不准确之外,我的风格问题还没有得到回答。我很可能会使用我在问题中提出的解决方案。
我们有一个可以建模为嵌套对象的资源
GET /A/
[
{
"name": "my_a",
"B": [
{"name": "my_b", "address": "0xbeef"}
]
}
]
或子资源,如
GET /A/my_a/B
[
{
"name":"my_b", "address": "0xbeef"
}
]
我们的客户想要一种方法来根据类型 B 的属性查询类型 A 的对象,例如"get me all the A objects who have B objects with name 'my_b'".
使用"B as a sub-resource" 的写作风格来编写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, nested objects, querying" 并找到了示例。这些示例中的大多数都将子资源作为嵌套对象包含在内,include_b
参数似乎是我的设计所特有的。
所以,所以,我正在寻找关于这种方法的一般反馈,看看这是否是已知解决方案的常见问题。很想知道返回的内容。
编辑 1: 更新了示例以显示查询可以针对任意属性。
正如@RomanVottner 所指出的,我实际上并不是在设计 RESTful API。相反,API 更接近于转换为使用 HTTP/JSON 的 RPC。事实上,我的团队遵循 Google API Design guide,它本身决定了如何编写 GRPC API,然后(我假设)自动将其转换为 Web 端点。
所以,在一天结束的时候,除了得知我的问题不准确之外,我的风格问题还没有得到回答。我很可能会使用我在问题中提出的解决方案。