POST和PUT的不同型号要求

问题描述 投票:5回答:2

假设我有一个控制器CatController,其中包含GET,POST和PUT的操作。他们都使用相同的Cat资源,看起来像这样:

public class CatDto {
  public int Id { get; set; }

  [Required]
  public string Name { get; set; }

  [Required]
  public bool IsFriendly {get; set; }
}

但是,仅在创建新cat(POST)时才需要NameIsFriendly属性,但在更新它(PUT)时可选,以允许仅更新单个属性。

到目前为止我处理这个问题的方法只是有两个类,一个CreateCatUpdateCat,它们具有相同的属性但是数据注释不同。但是我不想要维护两个几乎相同的类。

我当然可以在每个操作中手动验证模型,但数据注释对于诸如全局模型验证器和自动生成Swagger架构之类的东西非常有用。

我也使用Swagger模式自动生成SDK(使用ApiMatic),这导致生成两个重复的类(CreateCatUpdateCat),它们应该只是一个资源(Cat)。

有没有另一种方法来实现我只想用一个班级做的事情?

c# asp.net-web-api data-annotations
2个回答
3
投票

我更愿意保持单独的模型。您可以使用具有所有常见属性的基本抽象(或不具有)模型,尽管这不是必需的,只需添加第三个类。有必要吗?我会说不。

POST和PUT之间存在细微差别。如果您已在PUT端点中拥有Id属性,则POST和PUT都不需要Id属性。这使得无需检查URL中的Id是否与模型中的Id匹配。

您的示例不会显示差异,但在许多情况下,您确实不想更新某些字段。例如,假设您有一个Created和Updated日期字段,您不希望通过PUT更改您创建的日期。您不希望通过PUT更新的数据越多,模型之间的差异就越明显和有价值。

在您的情况下,即使使用这两个属性,我仍然会创建2个不同的模型,即使它们几乎相同,这也预示着API如何工作,并在其他所有人的脑海中创建一个清晰的设计。


1
投票

我建议不要考虑你要求的设计。根据RFC [RFC7231],您可以找到here,建议不要在PUT方法中进行部分内容更新。

“允许PUT在给定目标资源上的原始服务器必须向包含Content-Range头字段的PUT请求发送400(错误请求)响应([RFC7233]的第4.2节),因为有效载荷可能是部分的错误地将PUT作为完整表示的内容。通过将具有与较大资源的一部分重叠的状态的单独标识的资源作为目标,或者通过使用为部分更新专门定义的不同方法(例如,部分内容更新)是可能的。 ,[RFC5789]中定义的PATCH方法。“

首选的解决方案是使用PATCH方法代替PUT。补丁方法在本qazxsw poi的RFC中描述。引入PATCH方法用于部分资源修改

因此,查找PATCH方法或者如果您想使用PUT,可能有一个单独的端点,只接受两个值中的一个。

有关PATCH方法的更多信息可以在link找到

因此要么使用PATCH方法,要么使用PUT创建不同的模型和终点以满足部分更新。

© www.soinside.com 2019 - 2024. All rights reserved.