Java REST和复杂搜索查询
我正在寻找一种在RESTAPI中建模搜索查询的健壮方法 在MyAPI中,可以使用查询参数在资源的URI中指定搜索条件 例如:Java REST和复杂搜索查询,java,rest,search,Java,Rest,Search,我正在寻找一种在RESTAPI中建模搜索查询的健壮方法 在MyAPI中,可以使用查询参数在资源的URI中指定搜索条件 例如: /cars?search=颜色,蓝色;及;doors,4-->返回带有4扇门的蓝色汽车列表 /cars?search=颜色,蓝色;或doors,4-->返回蓝色或有4个车门的车辆列表 在服务器端,搜索字符串映射到所需的底层技术。根据rest资源的不同,这可以是SQL查询、Hibernate标准api、另一个webservice调用 这两个例子足够简单,可以支持,但我还需要
/cars?search=颜色,蓝色;及;doors,4-->返回带有4扇门的蓝色汽车列表
/cars?search=颜色,蓝色;或doors,4-->返回蓝色或有4个车门的车辆列表
在服务器端,搜索字符串映射到所需的底层技术。根据rest资源的不同,这可以是SQL查询、Hibernate标准api、另一个webservice调用
这两个例子足够简单,可以支持,但我还需要更复杂的搜索功能,如子字符串搜索、日期前后搜索,而不是
我认为这是一个常见的问题。是否有我可以使用的库(或模式):
- 将指定为字符串的搜索查询映射到通用条件模型。搜索格式不必与上面列出的格式相同李>
- 允许我将标准模型映射到我需要使用的任何技术李>
- 提供对Hibernate/JPA/SQL的映射支持,但这是一个额外的好处;)李>
Glenn您是否搜索像ODATA()这样的库
这将解决您的查询解析问题,您可以将查询转发到您选择的数据库。hmmm。。。这是一个棘手的领域。没有为您的问题量身定制的框架。即使@p0wl提到的ODATA也对字段映射到域模型的方式有一定的限制。一点之后就变得很奇怪了 解决这一问题的最简单方法是将查询作为字符串接受,然后使用AST或任何您想要的方法对特定于域的语言进行验证。这使您能够灵活地接受查询,同时验证其正确性。您失去的是通过URL以更有意义的方式描述查询的能力 看看Restful食谱食谱。它强调了我提出的解决方案之一,并推荐了其他方法。根据客户需要的灵活性和查询的表达能力选择一个。你可以在某个地方找到平衡。@GlennV 我不确定是否存在与此直接相关的模式/规则,以及这是否是一个常见问题(我指的是查询字符串中的逻辑运算符),但在设计类似内容时,我会问自己以下问题:
- 客户端将如何构造这样的查询李>
- 客户端可以通过“Link:”头或实体体(如atom或HTML链接或类似内容)跟踪包含在HTTP头中的链接
- 客户可以根据媒体类型或其他规范定义的规则构造URI
- HTML获取表单,其中表单字段根据表单的操作属性值(媒体类型引导)中提供的URI进行编码并附加到URI中李>
- URI模板(非常广泛,但值得一读,规范提供了非常有趣的特性)
- 连接器-其中包括HTTP+URI规范,实际上只有连接器对客户端起作用
- 组件-它是底层实现,除了您之外,没有人关心它。这一部分需要对客户完全隐藏,您可以在这里选择任何绑定方法,没有人可以告诉您确切的方式,这完全取决于特定的需求李>
/cars
有一个带搜索选项的分页汽车集合,这样当你得到/cars
时,它会返回类似的内容(顺便说一句,我在这里使用的是自定义媒体类型,但是表单和链接应该非常明显。如果没有,请告诉我):
这个结果让我们进一步完善我们的查询。所以只要说我们想要白色的车,而不是“非白色”的车,我们就可以得到“/cars?color=white&color2=off-white&color2 logic=not”,这可能会返回
<cars href="/cars?color=white&color2=off-white&color2-logic=not">
<car href="/cars/beta">...</car>
<car href="/cars/delta">...</car>
...
<next href="/cars?color=white&color2=off-white&color2-logic=not&page=2"/>
<search-color href="/cars?color=white&color2=off-white&color2-logic=not" method="GET">
<color3 type="string" cardinality="required"/>
<color3-match type="enumeration" cardinality="optional" default="substring">
<option name="exact"/>
<option name="substring"/>
<option name="regexp"/>
</color3-match>
<color3-logic type="enumeration" cardinality="optional" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</color3-logic>
</search>
<search-doors href="/cars?color=white&color2=off-white&color2-logic=not" method="GET">
<doors type="integer" cardinality="required"/>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
类似地,当我们细化颜色时,我们可能会发现它们只有几个选项,在这种情况下,我们可以从提供字符串搜索切换到提供枚举搜索。e、 例如,GETing/cars?color=white
可能会给我们
<cars href="/cars?color=white">
...
<search-doors href="/cars?color=white" method="GET">
<doors type="enumeration" cardinality="required">
<option name="2"/>
<option name="4"/>
</doors>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
<cars href="/cars?color=white">
...
<search-color href="/cars?color=white" method="GET">
<color2 type="enumeration" cardinality="required">
<option name="white"/>
<option name="off-white"/>
<option name="blue with white racing stripes"/>
</color2>
<color2-logic type="enumeration" cardinality="optional" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</color2-logic>
</search>
...
</cars>
...
...
您可以对其他搜索类别执行相同的操作。例如,最初您不想枚举所有make,因此您需要提供某种文本搜索。一旦收集
<cars href="/cars">
...
<search-doors href="/cars" method="GET">
<doors type="enumeration" cardinality="required">
<option name="2"/>
<option name="3"/>
<option name="4"/>
<option name="5"/>
</doors>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
<cars href="/cars?color=white">
...
<search-doors href="/cars?color=white" method="GET">
<doors type="enumeration" cardinality="required">
<option name="2"/>
<option name="4"/>
</doors>
<door-logic type="enumeration" cardinality="required" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</door-logic>
</search>
</cars>
<cars href="/cars?color=white">
...
<search-color href="/cars?color=white" method="GET">
<color2 type="enumeration" cardinality="required">
<option name="white"/>
<option name="off-white"/>
<option name="blue with white racing stripes"/>
</color2>
<color2-logic type="enumeration" cardinality="optional" default="and">
<option name="and"/>
<option name="or"/>
<option name="not"/>
</color2-logic>
</search>
...
</cars>