我们应该如何使用REST有效地访问多维数据?选择似乎是hi-REST,lo-REST或OpenSearch(这似乎是lo-REST的特化)。
最佳答案
为了使您的系统成为RESTful,要求之一是客户端不了解URI的结构。这意味着您不能像大多数twitter客户端那样编写以特定方式构建URI的代码。传统的观点是,为了找到资源,您需要在其他位置发现它的URI。
但是,有时您要处理系统中无数的资源,并且提供指向每个资源的链接只是愚蠢的。多维数据属于此类别。在这些情况下,向客户端提供URI构造规则是完全有效的,只要在运行时发现这些规则即可。
OpenSearch绝对是针对此问题的RESTful解决方案,并且它对程序员如此友好。 OpenSearch的许多用途仅限于普通的人类可读HTML搜索结果,但实际上,它也可用于纯机器可读(例如原子)搜索结果:
<Url type="application/atom+xml"
template="...search/?q={searchTerms}"/>
该模板指示客户,如果您想要原子表示,则可以转到此处。但这如何适合多维数据? OpenSearch的可扩展性在这里发挥了作用。 OpenSearch time extension描述了如何指示客户端构造表示限制在特定时间范围内的搜索的URL(假设
xmlns:time
正确绑定(bind):<Url type="application/atom+xml"
template="...search/?after={time:start}&before={time:end}"/>
如果客户看到此模板,则可以从模板中看到它仅允许时间限制。让我们自己扩展一下。
为了扩展OpenSearch,我必须指定一个 namespace 和该 namespace 中的某些元素来表示特定的内容。它应该在某个地方发布,以便其他人可以访问文档并实现自己的服务器和客户端。假设您想按姓氏查询客户;姓氏是一个非常通用的术语,但是不够通用,因此没有经过标准化。假设我定义了一个 namespace ,将其绑定(bind)到OpenSearch描述中的
name
前缀,并公开以下模板:<Url type="application/atom+xml"
template="...search?lastName={name:last}"/>
该模板指示任何了解我的
name
命名空间的客户端可以通过填写模板来执行姓氏查找。这仍然不是多维的,但让我们添加另一个维度。地理。幸运的是,有一个OpenSearch draft extension for geography,它允许在边界框或圆内进行搜索:
<Url type="application/atom+xml"
template="...search/?latitude={geo:lat?}&
longitude={geo:lon?}&
metres={geo:radius?}"/>
我正在拆分模板以使其可读。
该模板仍然不是多维的,因为它仅允许在一维(地理空间)内搜索。那么如何进行多维搜索?您提供了一个模板,该模板显示了如何进行多维搜索,将其组合起来很有意义:
例如。这是一个模板,可以让我在不同区域(二维)中找到具有给定姓氏的人:
<Url type="application/atom+xml"
template="combo-find?customerLastName={name:last}&
lat={geo:lat?}&
lon={geo:lon?}&
radius={geo:radius?}"/>
这是一个模板,可让我约束名称和地理空间以及时间限制(尽管OpenSearch Time扩展名并未说明您要寻找的时间):
<Url type="application/atom+xml"
template="...search/?lastName={name:last}&
lat={geo:lat?}&
lon={geo:lon?}&
r={geo:radius?}&
after={time:start}&
before={time:end}"/>
在这些示例中,客户端可以自由地查看URI模板以找出要填写的URI模板参数。因此,客户端将知道每个URI模板支持哪些维度,并且可以随时确定哪个URI最适合。
所有这一切的RESTful性是因为所有REST约束都得到遵守;它是无状态的,超媒体是引擎,它是分层的,等等。OpenSearch只是另一种超媒体格式,在这方面非常好!