简化RESTful搜索

REST体系结构模式基于两个基本原则:

  • 资源作为URL:在建模术语时,资源类似于实体或名词。 网络上的任何内容都被标识为资源,并且每个唯一资源都由唯一URL标识。
  • 作为HTTP方法进行操作: REST利用现有的HTTP方法,特别是GET,PUT,POST和DELETE,它们分别映射到资源的读取,创建,修改和删除操作。

客户端通过HTTP执行的任何操作都包含URL和HTTP方法。 URL代表资源,HTTP方法代表需要在资源上执行的操作。

作为一种广泛的建筑风格,REST总是有不同的解释。 由于几乎没有足够的HTTP方法来支持通用操作,这一事实加剧了这种歧义。 最常见的示例之一是缺少“ 搜索 ”方法。 搜索是跨不同应用程序使用最广泛的功能之一,但是没有实现该功能的标准。 因此,不同的人倾向于以不同的方式设计搜索。 鉴于REST旨在统一服务架构,因此任何歧义都必须视为削弱REST的理由。

在本文档的进一步内容中,我们将讨论如何简化基于REST的搜索。 我们的目标不是开发RESTful搜索的标准,但我们将讨论如何解决此问题。

搜索是不同Web应用程序中最常用的功能,它支持不同应用程序中几乎相似的功能。 以下是搜索功能的一些常见组成部分的列表:

  1. 一次基于一个或多个条件进行搜索
    • 搜索掀背车类型的红色汽车
    • 颜色=红色&&类型=掀背车
  2. 相对和有条件的操作员支持
    • 搜索里程大于10的红色或黑色汽车
    • 颜色=红色|黑色&&里程> 10
  3. 通配符搜索
    • 搜索以M开头的公司名称制造的汽车
    • 公司= M *
  4. 分页
    • 列出所有汽车,但一次获取100个结果
    • upperLimit = 200 && lowerLimit = 101
  5. 范围搜寻
    • 让我了解2000年至2010年之间推出的所有汽车
    • 发行年份(2000年至2010年)

当我们支持具有此类功能的搜索时,搜索界面设计本身就会变得复杂。 当在REST框架中实现时,要满足所有这些要求(同时仍然符合REST!),将具有挑战性。

回到基本的REST原则,现在剩下以下两个问题:

  1. 哪种HTTP方法用于“搜索”
  2. 如何创建有效的搜索资源网址?
    • 查询参数与嵌入式URL
    • 建模过滤条件

查询条件与嵌入式条件:有效地,REST按其性质对操作进行分类,并将定义明确的语义与这些类别相关联。 幂等运算为GET,PUT和DELETE(GET为只读,PUT为更新,DELETE为删除)。 而POST方法用于诸如create之类的非幂等过程。

根据定义本身,搜索是只读操作,用于请求基于某些条件过滤的资源集合。 因此,用于搜索功能的GET HTTP方法是显而易见的选择。 但是,使用GET时,如果我们在U​​RL中添加复杂的条件,则会受到URL大小的限制。

让我们以一个示例进行讨论:一个用户希望搜索蓝色的四门轿车; 该请求的资源网址应如何? 下面两个不同的URL在语法上不同,但在语义上相同:

  • / cars /?color = blue&type = sedan&doors = 4
  • /汽车/颜色:蓝色/类型:轿车/门数:4

以上两个URL均符合RESTful表示资源查询的方式,但表示方式有所不同。 第一个使用URL查询条件来添加过滤详细信息,而第二个则采用嵌入式URL方法。

嵌入式URL方法更具可读性,并且可以利用Web服务器上存在的用于HTTP流量的本机缓存机制。 但是这种方法限制用户以特定顺序提供参数。 错误的参数位置将导致错误或不良行为。 下面两个看起来相同,但可能无法为您提供正确的结果

  • /汽车/颜色:红色/类型:轿车
  • /汽车/类型:轿车/颜色:红色

同样,由于没有标准的嵌入标准,人们可能倾向于使用自己的表示方式。

因此,尽管表示形式有点复杂并且缺乏可读性,但是我们考虑使用查询标准方法而不是嵌入式URL方法。

建模过滤器标准:尽管搜索结果页面的URL标识了查询,但它基本上是RESTful的。 URL应能够合并类似SQL的元素。 尽管SQL旨在过滤从关系数据中获取的数据,但新的建模语言应能够从资源的分层集中过滤数据。 该语言应有助于设计一种机制,以通过URL传达复杂的搜索要求。 在本节中,将进一步详细讨论两种此类样式。

  • 提要项查询语言(FIQL):提要项查询语言(FIQL,发音为“变戏法”)是一种简单但灵活的URI友好语法,用于在联合提要中的各个条目之间表达过滤器。 这些过滤器表达式可以映射到任何RESTful服务,并且可以帮助对复杂的过滤器建模。 以下是针对此类Web URL及其相应SQL的一些示例。
的SQL
REST搜索URL
从演员中选择*,其中名=“ PENELOPE”和姓=“ GUINESS” / actors?_s = firstname == PENELOPE; lastname == GUINESS
从演员的姓氏中选择*,例如“ PEN%” / actors?_s = lastname == PEN *
从Filmid = 1和RentalDuration <> 0的电影中选择* / films?_s = filmid == 1;出租期限!= 0
从Filmid> = 995的电影中选择* / films?_s = filmid = ge = 995
从发行日期<'27 / 05/2005'的电影中选择* /film?_s=releasedate=le=2005-05-27T00:00:00.000%2B00:00
  • 资源查询语言(RQL) :资源查询语言(RQL)定义了一种语法上简单的查询语言,用于查询和检索资源。 RQL被设计为URI友好的,尤其是作为URI的查询组件,并且高度可扩展。 RQL是HTML表单值的URL编码的超集,也是Feed项目查询语言(FIQL)的超集。 RQL基本上由一组可嵌套的命名运算符组成,每个运算符都有一组参数,并对一组资源进行运算。

为了支持高级搜索功能,Apache CXF从2.3.0版本开始通过其JAX-RS实现引入了FIQL支持。 使用此功能,用户现在可以使用URI表示复杂的搜索表达式。 以下是有关如何使用此功能的详细说明:

要使用FIQL查询,需要将SearchContext注入到应用程序代码中,并用于检索代表当前FIQL查询的SearchCondition。 可以多种方式使用此SearchCondition查找匹配数据。

@Path("books")
public class Books {
 private Map books;
 @Context
 private SearchContext context;@GET
 public List getBook() {SearchCondition sc = searchContext.getCondition(Book.class);
 //SearchCondition is method can also be used to build a list of// matching beans iterate over all the values in the books map and
 // return a collection of         matching beans
 List found = sc.findAll(books.values());
 return found;
 }
}

SearchCondition还可以用于获取所有搜索要求(最初以FIQL表示),并与本地数据进行一些手动比较。 例如,SearchCondition提供了toSQL(String tableName,String…columnNames)方法的实用程序,该方法在内部对构成当前查询的所有搜索表达式进行内省,并将其转换为SQL表达式:

// find all conditions with names starting from 'ami'
// and levels greater than 10 :
// ?_s="name==ami*;level=gt=10"
SearchCondition sc = searchContext.getCondition(Book.class);
assertEquals("SELECT * FROM table
WHERE
name LIKE 'ami%'
AND
level > '10'",
sq.toSQL("table"));

数据查询是大多数应用程序的重要组成部分。 随着富客户端驱动的Ajax应用程序和面向文档的数据库的发展,需要新的查询技术。 这些技术必须简单但可扩展,旨在在URI中工作并查询资源集合。 NoSQL运动为数据库的更模块化方法开辟了道路,并将建模,验证和查询问题与存储问题分离开来,但是我们需要新的查询方法来匹配更现代的体系结构设计。


参考:来自JCG合作伙伴 Dustin Marx的Guava的Strings类,来自Inspired by Actual Events博客。

翻译自: https://www.javacodegeeks.com/2012/01/simplifying-restful-search.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值