多个可选的查询字符串参数REST API GET

我正在使用web api 2来实现一个宁静的服务。 在对最佳实践进行一些研究之后,每个人似乎都对如何做以下事情有不同的看法。 我有一个GET

public HttpResponseMessage Get(string crewId, string shiftDate, int offset = 1, int limit = 10) 

此GET方法返回一个列表。 有多种方法可以从此方法获取数据。

  • 仅限crewId
  • 仅限shiftDate
  • 要么

  • 通过crewId和shiftDate获取
  • 你(1)将crewId和shiftDate标记为可选吗?

     public HttpResponseMessage Get(string crewId = null, string shiftDate = null, int offset = 1, int limit = 10) 

    然后有一堆if语句来检查填充的内容和未填充的内容以便能够执行操作

     if(crewId != null && shiftDate == null){ // Get by crewId }else if(crewId == null && shiftDate != null){ // Get By shiftDate }else if(crewId != null && shiftDate != null){ // Get By crewId and shiftDate } 

    对我来说这看起来很疯狂,特别是如果你有很多参数,你的代码中会有太多“if”语句。

    你(2)有不同的获取?

     public HttpResponseMessage GetByCrewId(string crewId, int offset = 1, int limit = 10) public HttpResponseMessage GetByShiftDate(string shiftDate, int offset = 1, int limit = 10) public HttpResponseMessage GetByCrewIdShiftDate(string crewId, string shiftDate, int offset = 1, int limit = 10) 

    然后你将URI路由映射到方法

  • … / API / GetByCrewId?crewId = 1234
  • … / API / GetByShiftDate?shiftDate = 1111年11月11日
  • … / API / GetByCrewIdShiftDate?crewId = 1234&shiftDate = 1111年11月11日
  • 选项2是否宁静?

    或者有更好的选择(3)。

    上述两个选项都可以确保我使用最佳实践并遵循REST标准。 看起来我错过了一些东西,希望你能把我放在正确的方向。

    您不希望选项(2) – 在您的URL中想要名词的RESTful。

    所以你希望你的URL看起来像:

     /api/items/?crewId=1234&shiftDate=1111-11-11 

    (根据’船员’和’Shift’参数名称,我无法弄清楚你的物品是什么。什么有船员和轮class日期?钓鱼之旅?如果是这样,url会更好/ api /钓鱼人次/?crewId = ….&shiftDate = …

    至于控制器,我会去做类似的事情:

     public HttpResponseMessage Get(string crewId = null, string shiftDate = null, int offset = 1, int limit = 10) { return dataSource.Where(x=> (x.CrewId == crewId || crewId == null) && (x.ShiftDate == shiftDate || shiftDate == null)); } 

    我之前做过类似的事。 既然你可以使用其中一个或两个,我会使用可选参数:

     public HttpResponseMessage Get(string crewId = null, string shiftDate = null, int offset = 1, int limit = 10) 

    然后构建您的查询。 例如,像这样:

     var query = ""; if (!String.IsNullOrEmpty(crewId)) { query += $"crewId='{crewId}'"; } if (!String.IsNullOrEmpty(shiftDate)) { if (query.Length > 0) query += " AND "; query += $"shiftDate='{shiftDate}'"; } if (query.Length == 0) { //neither crewId or shiftDate were given //return some kind of error } 

    查看最佳实践:了解REST标头和参数它指出使用查询参数将指示它是可选的。 如果您可以创建一个单独的值而其他值是可选的,则可能有助于澄清URI。

     /api/fishing-trips/crew/{crewid}?shiftdate=1111-11-11 

    最后,如果您的商品都是可选的,那么使用“?” 可能是最好的路线。 有关参数类型的更多信息,请参见RFC 6570 。

    请注意,您的选择可能会对您选择使用的任何队列产生影响,并且路径样式参数扩展可能最有意义。 有关REST参数的更多信息。

    最后,您可能希望将它们创建为搜索参数,如果您发现用户经常请求相同的搜索,则可以将其打包到单个REST路径中。

    例如,

     /api/fishing-trips/search?crew=1234 /api/fishing-trips/search?shiftDate=1111-11-11 /api/fishing-trips/search?crew=1234&shiftDate=1111-11-11 

    您还可以提供简化以及可选参数,例如,

     /api/fishing-trips/today /api/fishing-trips/today?crew=1234 /api/fishing-trips/crew/1234/today 

    这些最后的例子在我的研究中是主观的,但更多信息可以在Pragmatic Rest API的最佳实践和用于搜索的RESTful URL设计中获得 。

    考虑到我自己即将实现这个,我会说它应该是一个带有多个可选参数的单个GET方法动作。

    为什么? 因为您不必担心REST API层中的此查询逻辑。 毕竟,您正在有效地创建具有多个参数的AND辨别子句(即CrewId = 1 AND ShiftDate = 2016-01-01 )。 如果您不提供参数,请返回所有项目。

    我将把我的参数一直传递给SQL存储过程,该过程具有指定的默认值,并将根据传递的参数返回结果。

    请记住,在许多方面,REST方法直接映射到CRUD,因此请将API视为: REST API教程