我有一个带有两个动作的Web API控制器。一个操作返回数据库中所有实体的列表。第二个操作采用查询字符串参数并过滤实体。
搜索操作已连接到使用查询字符串参数。它有效但我们遇到了一个问题,因为文档工具不相同,因为操作签名是相同的(文档工具没有考虑查询字符串)。
将搜索参数从查询字符串移动到路径中的属性是错误的吗?这是一种可接受的方法吗?威尔会引起我没想到的问题吗?
目前,这是我使用的网址:
domain.com/api/entities?q=xyz
我正在考虑采用基于路线的方法:
domain.com/api/entities/xyz
答案 0 :(得分:1)
如果要实现搜索功能或需要多个可选参数的其他类型的功能,最好使用查询字符串参数。你可以提供所有这些,其中一些,或者不提供任何一个,并按任何顺序放置它们,它就可以正常工作。
// Anything Goes
/controller/action?a=123&b=456&c=789
/controller/action?c=789&a=123&b=456
/controller/action?b=456&c=789
/controller/action?c=789
/controller/action
另一方面,如果您使用URL路径和路由,则只有在其右侧没有其他参数时,参数才可以是可选的。
// OK
/controller/action/123/456/789
/controller/action/123/456
/controller/action/123
// Not OK
/controller/action/123/456/789
/controller/action/456/789
/controller/action/789
这可能是customizing routing to be able to pass optional values in any order,但是当查询字符串非常适合这种情况时,似乎还有很长的路要走。
要考虑的另一个因素是,放入URL的值是否包含unsafe characters,需要进行编码。编码URL的路径的形式很差,有时也不可行,但是可以放入查询字符串的编码字符类型的规则更加宽松。由于URL不允许空格,因此更适合多字文本搜索字段使用查询字符串中的空格进行编码(保留原样),而不是尝试找到交换空间的解决方案使用-
放入查询字符串,然后在运行查询时必须将其更改回服务器端的空间。
search = "foo bar"
// Spaces OK
/controller/action?search=foo%20bar (works fine and server is able to interpret)
// Spaces Not OK
/controller/action/foo bar/ (not possible)
/controller/action/foo%20bar/ (may work, but a questionable design choice)
/controller/action/foo-bar/ (may work, but requires conversion on the server)
最后,值得考虑的另一个选择是使用POST而不是GET,因为这意味着这些值根本不需要在URL中。