【问题标题】:API versioning without duplicate code in C#在 C# 中没有重复代码的 API 版本控制
【发布时间】:2021-10-05 00:38:32
【问题描述】:

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

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

下面我的“更清洁”示例显然不起作用,因为在这种情况下你得到了 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();
        }

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

【问题讨论】:

    标签: c# .net asp.net-core .net-core routes


    【解决方案1】:

    您可以创建两个单独的函数作为 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();
        }
    

    【讨论】:

    • 这几乎就是我最终要做的,我为过时的路线制作了一个函数,并使其引用了新的路线代码。 return await GetChannelsV2(); 第一个函数返回第二个函数的结果。第三个不是必需的。感觉还是有点像没用的代码,不过暂时还好。
    【解决方案2】:

    尝试使用

    [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

    【讨论】:

      猜你喜欢
      • 2016-08-13
      • 2021-03-29
      • 2017-09-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多