RESTful API 过滤多个资源的多个查询字符串

RESTful API Multiple Query Strings over multiple Resources for Filtering

假设有一个实体公司和一个实体国家。一个公司可以属于多个国家,一个国家可以有多个公司。因此,有一个中间 table 成员资格,对公司具有不同的角色,例如一家公司是一个国家的制造商,另一家公司是一个国家的供应商。一个国家可以有多个状态,例如 is_active 等

现在我们要从角色为制造商且国家状态为 is_active = false 的特定公司获取所有国家。

RESTful API 端点如何查找此用例?是否允许过滤多个资源?一些想法:

GET /companies/{id}/nations?role=manufacturer&is_active=false

GET /memberships/{id}/nations?role=manufacturer&is_active=false

更新 也许我的问题不够清楚。查询字符串参数在两个不同的 tables/entities 中进行查找。角色在 memberships 实体内部,is_active 在 nations 实体内部。我认为只允许对请求的资源进行过滤。也许我可以把这个问题分成两个用例。

1) 是不是"better"去URI中的中间资源? 2) 我们可以在多个 tables/entities?

上使用查询字符串参数过滤资源吗

REST 不关心您使用什么拼写作为您的标识符。编码到 URI 中的任何数据均由服务器自行决定并供其自己使用。

这基本上意味着只要您的 URI 符合 RFC 3986,您就在做正确的事。这意味着:

Hierarchical data 属于路径 - 允许通用客户端以正确的方式解析相对引用。非分层数据属于查询。

Is it allowed to filter over multiple resources?

换句话说 - 标识符与 单个 资源匹配,该资源可能 load/filter 来自多行数据的状态。

GET /companies/{id}/nations?role=manufacturer&is_active=false
GET /companies/{id}/nations?role=manufacturer&is_active=true

这是两个不同的资源;它们恰好由相同的参数化查询支持的事实是一个实现细节。

The query string parameters make a lookup in two different tables/entities.

这是一个实施细节。就 API 消费者而言,您可能只是从键值存储中提取准备好的文档。

这就是要点的一部分,这里 - API 应该是 stable,即使底层实现需要更改。将集成接口与当前数据模式紧密耦合会使向后兼容的更改变得更加困难。

I thought that filtering is allowed only on the requested resource.

没有。就 REST 而言,整个 URI 是一个标识符。客户端使用该 URI 来访问和操作资源。接口背后的资源实现完全没有 REST 约束。它可以是文档存储、单个 table、多个 table、第 3 方服务、所有这些的某种组合....

您用来提供当前表示的服务器端框架可能会关心 -- 某些标识符比其他标识符更适合您的路由策略,该框架可能会限制您使用数据需要存储在单一的地方。但这些都只是实现细节。 REST 不关心。

Can we filter a resource with query string parameters over multiple tables/entities?

“过滤资源”的拼写不太正确,因为它混淆了您的 集成 资源(REST 关心的东西)与您的数据模型。

是否可以根据存储在多个 table 中的数据创建单个资源的表示?当然。是否可以将资源限制为满足某些过滤规范的 table 中的数据?当然。对于哪些过滤器可以应用于哪些 table 是否有任何限制?号

吉姆·韦伯:

URI do NOT map onto domain objects - that violates encapsulation.... You should expect to have many many more resources in your integration domain than you do business objects in your business domain.

这是在 SlashDB 中实现的自以为是的答案。

考虑这个场景,它与你的非常相似:

Track -< PlaylistTrack >- Playlist

一个曲目可以在多个播放列表中,一个播放列表通常由许多曲目组成。下面的 URL 是可点击的,将显示资源的 HTML 表示:

这是播放列表的 URI "Classical":

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical

现在,让我们切换到直通 table PlaylistTrack

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack

由于 PlaylistTrack 与 Track 有关系,我们可以将其添加为最后一段:

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack/Track

您可以选择遵循相同的模式。当实现通用时,它将允许对您的数据模型进行非常惊人的过滤和遍历。

例如,让我们查找 Classical 播放列表中曲目的发票,但仅限于来自法国、奥地利或意大利的曲目,并且仅限于总金额在 3 到 10 美元之间的曲目。

https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack/Track/InvoiceLine/Invoice/BillingCountry/France,Austria,Italy/Total/3..10