restful
REST体系结构模式基于两个基本原则:
- 作为URL的资源:在建模语言时,资源就像实体或名词。 Web上的任何内容都被标识为资源,每个唯一的资源都由唯一的URL标识。
- 作为HTTP方法进行操作: REST利用现有的HTTP方法,特别是GET,PUT,POST和DELETE,它们分别映射到资源的读取,创建,修改和删除操作。
客户端通过HTTP执行的任何操作都包含URL和HTTP方法。 URL代表资源,HTTP方法代表需要在资源上执行的操作。
作为一种广泛的建筑风格,REST总是有不同的解释。 由于几乎没有足够的HTTP方法来支持通用操作,这一事实使这种歧义更加恶化。 最常见的示例之一是缺少“ 搜索 ”方法。 搜索是跨不同应用程序使用最广泛的功能之一,但是没有实现该功能的标准。 因此,不同的人倾向于以不同的方式设计搜索。 鉴于REST旨在统一服务架构,因此任何歧义都必须视为削弱REST的理由。
在本文档的进一步内容中,我们将讨论如何简化基于REST的搜索。 我们的目标不是开发RESTful搜索的标准,但我们将讨论如何解决此问题。
搜索是不同Web应用程序中最常用的功能,它支持不同应用程序中几乎相似的功能。 以下是搜索功能的一些常见组成部分的列表:
- 一次基于一个或多个条件进行搜索
- 搜索掀背车类型的红色汽车
- 颜色=红色&&类型=掀背车
- 相对和有条件的操作员支持
- 搜索里程大于10的红色或黑色汽车
- 颜色=红色|黑色&&里程> 10
- 通配符搜索
- 搜索以M开头的公司名称制造的汽车
- 公司= M *
- 分页
- 列出所有汽车,但一次获取100个结果
- upperLimit = 200 && lowerLimit = 101
- 范围搜寻
- 让我了解2000年至2010年之间推出的所有汽车
- 发行年份(2000年至2010年)
当我们支持具有此类功能的搜索时,搜索界面设计本身就会变得复杂。 当在REST框架中实现时,要满足所有这些要求(同时仍然符合REST!),将是具有挑战性的。
回到基本的REST原则,现在剩下以下两个问题:
- 哪种HTTP方法用于“搜索” ?
- 如何创建有效的搜索资源网址?
- 查询参数与嵌入式URL
- 建模过滤条件
查询条件与嵌入式条件:有效地,REST按其性质对操作进行分类,并将定义明确的语义与这些类别相关联。 幂等运算为GET,PUT和DELETE(GET为只读,PUT为更新,DELETE为删除)。 POST方法用于诸如create之类的非幂等过程。
根据定义本身,搜索是只读操作,用于请求基于某些条件过滤的资源集合。 因此,用于搜索功能的GET HTTP方法是显而易见的选择。 但是,使用GET时,如果我们在URL中添加复杂的条件,则会受到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
restful