API 版本控制 - 如果模型发生变化我该怎么办

Box*_*xed 4 c# api swagger asp.net-core

我对 API 和版本控制相当陌生,但据我了解,如果 API 出现违反合同的变更,开发人员(即我)应该保留代码。如果我错了,请纠正我,但我认为模型变更是违反合同的变更。

所以我的问题是 - 您是否只是为了版本控制而创建新模型(例如 ModelName.V2)?有一个更好的方法吗?这意味着即使我的模型中的属性发生轻微变化,我也会将其迭代到另一个版本。

ps,如果我需要编辑我的问题,请告诉我,因为我对 StackOverflow 也相当陌生。

样本

public class Product
{
    public int ID {get;set;}
    public string Name {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

和随附的控制器

[ApiVersion("1.0")]
[Route("api/v{version:apiVersion}/[controller]/[action]")]
public class Products : Controller
{
   Product[] prod = new Product[]{
       new Product(){ID = 1, Name = "T-Shirt"},
       new Product(){ID = 2, Name = "Jeans"}
   };


   [HttpGet]
   [ActionName("gotcha")]
   public IActionResult GetProduct()
   {
       return Ok(prod);  
   }
}
Run Code Online (Sandbox Code Playgroud)

对于 V2 控制器

[ApiVersion("2.0")]
[Route("api/v{version:apiVersion}/[controller]/[action]")]
public class V2.Products : Controller
{
       [HttpGet]
       [ActionName("gotcha")]
       public IActionResult GetProduct()
       {
           var trash = "Hello World!";
           return OK(trash);  
       }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码是我所理解的合同破坏和所需的版本控制,下面是我的模型合同破坏问题:

public class Product
{
   public int ID {get;set;}
   public string Name {get;set;}
   public decimal Price {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

所以上面的示例显示我添加了一个新属性。我认为这违反了合同,我是否迭代新的控制器版本,然后保留旧模型?将来如果我保留旧版本,这会很混乱。

Chr*_*att 6

首先,只有在发生重大更改时才需要恢复。并非所有内容都一定是重大更改,通常添加新属性实际上并不是重大更改。过时的客户应该简单地忽略它,如果没有,这对客户来说比你更重要,因为他们会做一些奇怪/错误的事情来导致任何事情破坏这种方式。您需要更加关注更改或删除,从客户的角度来看,这两者是同一件事;进行更改后,就好像旧属性被删除并添加了新属性一样。但即便如此,只有名称或类型发生变化才重要。任何幕后处理都无关紧要,从技术上讲,即使您更改属性名称,JsonProperty如果您愿意,也可以利用类似属性的东西使序列化返回旧名称。

假设您确实重大更改,那么是的,您应该创建模型类的新版本,可能还需要创建一个新的操作/控制器,两者都以新版本号命名,即Product2GetProduct2/或Product2Controller等。是的,这可能会导致代码重复,但是您可以采取两件事来最大限度地减少这种情况:

  1. 如果可能的话使用继承。例如,Product2可以继承Product并简单地覆盖需要更改的任何属性。如果您只是添加一个新GetProduct2操作,您可以将原始代码分解GetProduct为私有通用方法GetProduct2<TProduct>,然后重新实现原始(和新)方法以简单地返回该方法,即return GetProduct<Product>();GetProduct return();`。这些只是示例。有许多不同的方法可以处理这个问题,但要点是它不一定需要大量代码重复来进行版本控制。

  2. 如果您发现您的代码库开始变得混乱,您可以开始弃用 API 版本。向您的客户发出通知,告知您的一个或多个最旧版本现已弃用。然后,经过一段合理的时间(取决于更新所需更改的复杂性),在新版本中删除旧代码。这当然会破坏任何过时的客户,但他们会被预先警告并有时间进行更改,所以如果他们不这样做,那就是他们的责任。你会发现所有的大男孩时不时都会这样做。我知道我收到了大量来自 Facebook 的电子邮件,警告待删除的 API 版本。这本质上就是他们在幕后所做的事情:清理他们的代码库。