API 在 C# 中没有重复代码的版本控制

API versioning without duplicate code in C#

我有一种情况,我正在向 API 添加版本控制,因此某些 API 函数的路由发生了变化。我还将一些方法从 POST 更改为 GET,因为它更有意义。

我想弃用旧路线,以便人们开始使用新路线。我希望旧路由绑定到我的 API 的 v1,而新路由绑定到 v2。 我通过复制所有函数并用正确的路由、方法和 api 版本标记它们来实现这个工作,但我希望有一个更清晰的解决方案。

下面我的 'cleaner' 示例显然不起作用,因为在这种情况下你得到 4 个函数,它们都已弃用。

你得到:

  1. HTTPGET /频道
  2. HTTPPOST/频道
  3. HTTPGET /api/v2/channels/get
  4. HTTPPOST/api/v2/channels/get
        /// <summary>
        /// Gets a list of all channels
        /// </summary>
        /// <returns>List of all channels</returns>
        [HttpPost, Route("~/channels"), ApiVersion("1.0"), Obsolete("Obsolete, please use /api/v2/channels/get")]
        [HttpGet, Route("Get"), ApiVersion("2.0")]
        public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannels()
        {
            return await _context.Monitors.ToListAsync();
        }

有什么方法可以让它工作吗?

您可以创建两个单独的函数作为 API 内部逻辑的“访问点”。其中一个可以标记为过时并使用旧路线,另一个将使用新路线。然后您可以创建第三个函数,其中包含 API.

的实际逻辑
    // The obsolete access point
    [HttpPost, Obsolete("Obsolete, please use /api/v2/channels/get"), ApiVersion("1.0")]
    public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannelsOld()
    {
        return await GetChannelsLogic();
    }

    // The new access point
    [HttpGet, ApiVersion("2.0")]
    public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannelsNew()
    {
        return await GetChannelsLogic();
    }
    //Marked as NonAction so the method can't be accessed by a request. This is not necessary depending on the setup of your project.
    [NonAction]
    public async Task<ActionResult<IEnumerable<DbChannel>>> GetChannelsLogic()
    {
        // Perform some other logic
        return await _context.Monitors.ToListAsync();
    }

尝试使用

[HttpPost("~/channels"), ApiVersion("1.0"), Obsolete("Obsolete, please use /api/v2/channels/get")]
        [HttpGet("Get"), ApiVersion("2.0")]
        public async Task<ActionResult<IEnumerable<string>>> GetChannels()
        {
            return new List<string>();
        }

这样你就只能有两条路线

  1. HTTPPOST /频道
  2. HTTPGET /api/v2/channels/get