让我们假设有一个实体公司和一个实体国家。一个公司可以属于许多国家,一个国家可以拥有多个公司。因此,存在具有公司不同角色的中间表成员资格,例如公司是一个国家的制造商,另一家公司例如是一个国家的供应商。一个国家可以有多种状态,如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
更新 也许我的问题不够明确。查询字符串参数在两个不同的表/实体中进行查找。角色在成员实体内部,is_active在国家实体内。我认为只允许在请求的资源上进行过滤。也许我可以在两个用例中分解问题。
1)使用URI中的中间资源是否“更好”? 2)我们可以使用多个表/实体上的查询字符串参数过滤资源吗?
答案 0 :(得分:2)
REST并不关心您用于标识符的拼写。编码到URI中的任何数据都由服务器自行决定,并供自己使用。
这基本上意味着只要您的URI符合RFC 3986,您就是在做正确的事情。这意味着:
Hierarchical data属于路径 - 允许通用客户端以正确的方式解析相对引用。非分层数据属于查询。
是否允许过滤多个资源?
其他方式 - 标识符与单个资源匹配,可以从多行数据加载/过滤状态。
GET /companies/{id}/nations?role=manufacturer&is_active=false
GET /companies/{id}/nations?role=manufacturer&is_active=true
这是两个不同的资源;它们恰好由相同的参数化查询支持的事实是一个实现细节。
查询字符串参数在两个不同的表/实体中进行查找。
这是一个实施细节。就API消费者而言,您可以将准备好的文档从关键值存储中拉出来。
这一点的部分内容 - 即使底层实施需要改变,API也应该是稳定的。将集成接口紧密耦合到当前的数据模式会使向后兼容的更改变得更加困难。
我认为只允许在请求的资源上进行过滤。
没有。就REST而言,整个URI是单个标识符。客户端使用该URI来访问和操作资源。在接口背后的资源实现看起来绝对没有REST约束。它可以是文档存储,单个表,许多表,第三方服务,所有这些的某种组合....
您用来提供当前表示的服务器端框架可能会关心 - 某些标识符与您的路由策略相比更适合其他标识符,框架可能会限制您将数据存储在一个地方的约定。但这些都只是实施细节。 REST并不关心。
我们可以使用多个表/实体上的查询字符串参数过滤资源吗?
"过滤资源"并不是一个非常正确的拼写,因为它会将您的集成资源(REST关心的东西)与您的数据模型混淆。
可以从存储在多个表中的数据创建单个资源的表示吗?当然。资源是否可以限制为满足某些过滤规范的那些表中的数据?当然。对哪些过滤器可以应用于哪些表有什么限制?否。
吉姆韦伯:URI不会映射到域对象 - 这违反了封装....您应该希望集成域中的资源比业务域中的业务对象多得多。
答案 1 :(得分:0)
这是SlashDB中实施的一个自以为是的答案。
请考虑这种情况,与您的非常相似:
追踪 - < PlaylistTrack> - 播放列表
曲目可以在许多播放列表中,播放列表通常由许多曲目组成。以下URL是可点击的,将显示资源的HTML表示:
以下是播放列表" Classical":
的URIhttps://demo.slashdb.com/db/Chinook/Playlist/Name/Classical
现在,让我们转到传递表PlaylistTrack
https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack
由于PlaylistTrack与Track有关系,我们可以将其添加为最后一段:
https://demo.slashdb.com/db/Chinook/Playlist/Name/Classical/PlaylistTrack/Track
您可以选择遵循相同的模式。一般实现时,它将允许非常惊人的过滤和遍历您的数据模型。
例如,让我们在古典播放列表中找到曲目的发票,但只能找到来自法国,奥地利或意大利的曲目发票,而只能找到总价在3到10美元之间的发票。