我正在使用web api 2来实现一个宁静的服务。在对最佳实践进行一些研究之后,每个人似乎都对如何做以下事情有不同的看法。我有一个GET
public HttpResponseMessage Get(string crewId, string shiftDate, int offset = 1, int limit = 10)
此GET方法返回一个列表。有多种方法可以从此方法获取数据。
你(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路由映射到方法
选项2是否安宁?
或者有更好的选择(3)。
上述两个选项都可以确保我使用最佳实践并遵循REST标准。看起来我错过了一些东西,希望你能让我朝着正确的方向前进。
答案 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 API和RESTful URL design for search提供了更多信息。
答案 3 :(得分:1)
考虑到我即将自己实现这个,我会说它应该是一个带有多个可选参数的GET
方法操作。
为什么呢?因为您不必担心REST API层中的此查询逻辑。毕竟,您正在有效地创建具有多个参数的AND
歧视条款(即CrewId = 1 AND ShiftDate = 2016-01-01
)。如果您不提供参数,请返回所有项目。
我将把我的参数一直传递给一个SQL存储过程,该过程具有指定的默认值,并将根据传递的参数返回结果。
请记住,在许多方面,REST方法直接映射到CRUD,因此请将API视为:REST API Tutorial