每当遇到这些问题时,我都会问自己:“如果我正在创建传统网页,该如何向用户展示”?简单的答案是,我不会在单个页面中显示这些选项。接口太复杂了。但是,我可以做的是提供一个界面,该界面允许用户在多个页面上建立越来越复杂的查询,这就是我认为在这种情况下应该采用的解决方案。
HATEOAS约束指定我们必须在响应中包括超媒体控件(链接和表单)。因此,假设我们有一个
/cars带有搜索选项的分页汽车集合,这样当您获得
/cars它时,它会返回类似(顺便说一句,我在这里使用的是自定义媒体类型,但是表单和链接应该很明显。让我知道不是):
<cars href="/cars"> <car href="/cars/alpha">...</car> <car href="/cars/beta">...</car> <car href="/cars/gamma">...</car> <car href="/cars/delta">...</car> ... <next href="/cars?page=2"/> <search-color href="/cars" method="GET"> <color type="string" cardinality="required"/> <color-match type="enumeration" cardinality="optional" default="substring"> <option name="exact"/> <option name="substring"/> <option name="regexp"/> </color-match> <color-logic type="enumeration" cardinality="optional" default="and"> <option name="and"/> <option name="or"/> <option name="not"/> </color-logic> </search> <search-doors href="/cars" 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>
因此,只要说我们搜索白色汽车,我们就会得到GET
/cars?color=white,我们可能会得到类似的信息:
<cars href="/cars?color=white"> <car href="/cars/beta">...</car> <car href="/cars/delta">...</car> ... <next href="/cars?color=white&page=2"/> <search-color href="/cars?color=white" method="GET"> <color2 type="string" cardinality="required"/> <color2-match type="enumeration" cardinality="optional" default="substring"> <option name="exact"/> <option name="substring"/> <option name="regexp"/> </color2-match> <color2-logic type="enumeration" cardinality="optional" default="and"> <option name="and"/> <option name="or"/> <option name="not"/> </color2-logic> </search> <search-doors href="/cars?color=white" 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>
然后,这个结果让我们优化查询。因此,只要说我们想要白色汽车而不是“灰白色”汽车,我们就可以获取’/ 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>
然后,我们可以进一步优化查询,但要点是,在此过程的每个步骤中,超媒体控件都会告诉我们什么是可能的。
现在,如果我们考虑汽车的搜索选项,那么颜色,车门,品牌和型号并不是无限制的,因此我们可以通过提供枚举使搜索选项更加明确。例如
<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>
但是,我们仅有的白色轿车可能是2门和4门,在这种情况下,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?color=white可能给我们
<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>
您可以对其他搜索类别执行相同的操作。例如,最初您不希望列举所有品牌,所以您将提供某种文本搜索。一旦对集合进行了精炼,并且只有几个模型可供选择,那么提供枚举就很有意义。相同的逻辑适用于其他集合。例如,您不希望枚举世界上所有的城市,但是一旦您将区域细化为10个左右的城市,则对它们进行枚举将非常有帮助。
有图书馆可以帮您吗?我不知道。我见过的大多数人甚至都不支持超媒体控件(即,您必须自己添加链接和表单)。有没有可以使用的模式?是的,我相信以上是解决此类问题的有效模式。



