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

时间:2016-01-19 16:46:11

标签: c# rest asp.net-web-api asp.net-web-api2

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

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

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

  • 仅限于船员
  • 仅限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标准。看起来我错过了一些东西,希望你能让我朝着正确的方向前进。

    4 个答案:

    答案 0 :(得分:5)

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

    所以你希望你的网址看起来像:

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

    (根据'船员'和'Shift'参数名称,我无法弄清楚您的物品是什么。什么有船员和班次日期?钓鱼之旅?如果是这样,网址会更好as / api / fishing-trips /?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));
    }
    

    答案 1 :(得分:2)

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

    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
    }
    

    答案 2 :(得分:2)

    回顾Best Practices: Understanding REST Headers and Parameters它表明使用query参数表明它是可选的。如果您可以创建一个值,而其他值可选,则可能有助于澄清URI。

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

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

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

    最后,您可能希望将这些作为搜索参数创建,如果您发现用户经常请求相同的搜索,则可以将其打包到单个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
    

    这些最后的例子来自我的研究,但Best Practices for a Pragmatic Rest APIRESTful URL design for search提供了更多信息。

    答案 3 :(得分:1)

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

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

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

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