PUT查询字符串的正确格式如何?

时间:2019-06-27 23:14:13

标签: c# rest routes put

我需要构建一个PUT方法,该方法将接收保险单号和相关期间的开始日期。该方法将更新开始相关时间段,因此,由于有更新,因此该方法被定义为PUT动词。

我的方法正确的格式是什么?我对两种可能的正确格式感到困惑:

http://<url>:<port>/api/valuation/<policy number>/<start date>

http://<url>:<port>/api/valuation/<policy number>

从身体接收日期?

在两种情况下,我如何声明路由(我使用的是.net framework 4.5)

对于选项#1

[Route("UpdatePeriod/{numPolicy}/{startDate}")]
public IHttpActionResult UpdatePeriod(string numPolicy, string startDate)

对于选项#2

[Route("UpdatePeriod/{numPolicy}")]
public IHttpActionResult UpdatePeriod(string numPolicy, [fromBody] string startDate)

有人可以给我提示吗?我对此有些迷茫。

谢谢。

1 个答案:

答案 0 :(得分:1)

这可能取决于偏好,但是我要补充的是,这实际上是关于以合理的方式组织URL,使用名词和动作有意义。因此,实际上是在遵循最佳实践和约定的情况下,以最直观,最合理的方式表示数据的工作方式。

因此,让我们看看您的示例。

http://<url>:<port>/api/valuation/<policy number>/<start date>

在我看来,这似乎代表着这样的数据,即存在具有相同保单号的多个保险单,并且您希望将其过滤为提供起始日期的一项。我不确定您的数据看起来如何,或者给定保单编号是否总是应该有一份有效的保险单,但这对我来说意义不大。

http://<url>:<port>/api/valuation/<policy number>

这向我暗示,给定保单编号,有一份保险单。这似乎是更可能的情况,所以我将从这一情况作为情况1开始。

场景1

如果您知道要使用一份有效的给定保单号的保险单,则在URL中包含开始日期 是没有意义的。您需要在通过身体获得的POST数据中使用它,因为您将按照该保险单行事。在这种情况下,#2是您的下注,you'll want to make "valuation" plural

您的URL看起来像这样:

# returns all insurance policies`
GET "http://<url>:<port>/api/valuations"

# returns one insurance policy with given policy number
GET "http://<url>:<port>/api/valuations/<policy number>"

# acts upon the insurance policy with that number, very broad
PUT "http://<url>:<port>/api/valuations/<policy number>"

# acts upon the insurance policy with number but in a more specific way with a dedicated method 
# start date would be in your post that you would then bind to a view model
PUT "http://<url>:<port>/api/valuations/<policy number>/startdate"

场景2

如果您知道要给定一个保险单号就可以提取多个保险单,并希望在开始日期之前进行过滤,那么将其包含在URL中就很有意义。该网址看起来像这样:

PUT http://<url>:<port>/api/valuations/<policy number>/startdate/<start date>

为什么?因为您要使用的保险单列表中的一个保险单具有相同的保险单编号,但开始日期不同。

因此您的网址看起来像这样:

# returns all valuations insurance policies`
GET "http://<url>:<port>/api/valuations"

# returns list of insurance policies with the same policy number
GET "http://<url>:<port>/api/valuations/<policy number>"

# return one insurance policy with the policy number and start date
GET "http://<url>:<port>/api/valuations/<policy number>/startdate/<start date>"

# updating information for that ONE policy with policy number and start date
PUT "http://<url>:<port>/api/valuations/<policy number>/startdate/<start date>"

我的答案基于基于名词的API网址而不是基于动词的网址。  有关更多信息,请访问:Confusion Between Noun vs. Verb in Rest URLs


如果您将开始日期作为POST参数传递,则应该将其绑定到视图模型:

class ValuationPolicyStartDateViewModel
{
   public DateTime? StartDate { get; set; }
}

// then in your controller
// PUT StartDate = "01/22/2018" will then be bound to your  view model
public IHttpActionResult UpdatePolicyByStartDate(string policyNumber, [FromBody] ValuationPolicyStartDateViewModel viewModel)
{
   ... code that validates etc ...
}

TL; DR

如果/api/valuation/<policy number>返回1张保险单,请在示例中使用选项2,并将“估价”设为复数。

如果/api/valuation/<policy number>返回了多个保险单,那么您应该做几件事:将valuation更改为valuations,然后将startdate添加为过滤变量。