【发布时间】:2016-09-07 13:18:27
【问题描述】:
我们希望在接受标头中使用内容协商来实现基于版本的 API。
我们能够通过一些继承和扩展默认 HTTP 选择器来实现控制器和 API 方法。
使用以下示例代码实现控制器继承,
public abstract class AbstractBaseController : ApiController
{
// common methods for all api
}
public abstract class AbstractStudentController : AbstractBaseController
{
// common methods for Student related API'sample
public abstract Post(Student student);
public abstract Patch(Student student);
}
public class StudentV1Controller : AbstractStudentController
{
public override Post([FromBody]Student student) // student should be instance of StudentV1 from JSON
{
// To Do: Insert V1 Student
}
public override Patch([FromBody]Student student) // student should be instance of StudentV1 from JSON
{
// To Do: Patch V1 Student
}
}
public class StudentV2Controller : AbstractStudentController
{
//
public override Post([FromBody]Student student) // student should be instance of StudentV2 from JSON
{
// To Do: Insert V2 Student
}
}
public abstract class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class StudentV1 : Student
{
}
public class StudentV2 : Student
{
public string Email { get; set; }
}
我们已经创建了上述架构,以减少版本更改的代码,例如,如果版本 1 有 10 个 API 方法并且其中一个 API 方法发生变化,则它应该在版本 2 代码中可用,而无需修改其他 9 个(它们是继承自版本 1)。
现在,我们面临的主要问题是合同版本控制,因为我们无法实例化抽象学生的实例。当有人将 JSON 发布到 API 版本 1 时,StudentV1 的实例应该在方法中传递,并且在版本 2 中也是如此。
有什么办法可以做到吗?
提前致谢!!
【问题讨论】:
-
感谢@DanielStackenland!我们没有像 productType 这样的通用字段来识别发布的 JSON。此外,我们将有大约 50 - 70 个这样的类,例如 API 中的学生,稍后将在需要时进行版本化。
-
AbstractStudentController 的目的到底是什么?为什么不让 StudentV1Controller(和 V2)继承 AbstractBaseController 并使用 StudentV1(和 V2)作为参数?
-
@DanielStackenland- AbstractStudentController 用于声明所有版本的 API 合同。我们不能使用 StudentV1 和 StudentV2,因为不能在控制器合同中使用继承。主要目的是,如果我们在版本 1 中有 10 个 API 方法,并且如果只需要对一个 API 方法进行合约更改,那么只需要在版本 2 控制器中覆盖它,其他 9 个将被版本 2 继承。数据合约应基于反序列化该 API 的相应版本。如果需要,我们可以将具体类的 API 归因于 API,但不能在参数中。
标签: asp.net asp.net-mvc asp.net-web-api asp.net-web-api2 versioning