UseSwaggerUI :: UseRequestInterceptor => 根据请求添加 api 版本

问题描述

尝试通过 Header 设置 API 版本控制。 其他一切正常,解决了每个人都知道具有相同端点的 api 版本的现有冲突。

但是它有一个问题,因为它只会使用认的 api 版本进行请求; 在探索了一些其他选项之后,似乎最好的方法是处理“UseRequestInterceptor”;

我的问题是我实际上对如何声明要在这里使用的函数一无所知;试图在注入的 javascript 文件上声明函数,但似乎不是正确的方法

周围的人可以给我一个线索吗? 谢谢

解决方法

对于那些可能想得到我想要的东西的人。

实际上有两个答案:

  • 根据标头请求使用版本进行版本控制
  • 大摇大摆的 UseRequestInterceptor howTo\syntax。

对于尝试使用 swagger 添加 api 版本控制并为每个版本具有相同端点的人,您将遇到关于无法为 2 个方法使用相同端点的错误。文档说对于休息服务你不应该这样做 - 对我来说这不是一个正确的答案,因为虽然我可能追求不同的预期结果或不同的性能,但我不想破坏消费者。

所以第一个解决方法:

            services.AddSwaggerGen(options =>
            {
                options.ResolveConflictingActions(o => o.FirstOrDefault());
                
                options.SwaggerDoc("v1",new OpenApiInfo { Title = "api.swagger.Versioning",Version = "v1" });
                options.SwaggerDoc("v2",Version = "v2" });
            });

通知解决冲突行; 这一行选择第一个版本,这没关系 - 或者不;

对于任何请求,它都不会抛出版本 api 的标头。这将以您所做的任何请求结束,将针对默认版本。不错!

在测试了一些选项并阅读之后,有了使用 UseRequestInterceptor 的想法,但错过了如何使用的语法。

对于我的代码,我选择将版本标头作为“api”;

所以最后你会得到类似的东西:

        public void Configure(IApplicationBuilder app,IWebHostEnvironment env)
        {
            app.UseCustomMiddleware();
            if (env.IsDevelopment())
            { 

                app.UseDeveloperExceptionPage();
                app.UseSwagger();
                app.UseSwaggerUI(swaggerUiOptions =>
                {
                    swaggerUiOptions.HeadContent = "Swagger API demo";


                    var fn =  "(request) => { var swaggerSelect = document.querySelector('#swagger-ui .swagger-container .topbar select'); if(swaggerSelect) { var selected = swaggerSelect.selectedOptions; if( selected ) { var version = selected[0].text.split('|')[1]; request.headers['api']=version; }  }; return request; }";


                
          
                    swaggerUiOptions.SwaggerEndpoint("/swagger/v1/swagger.json","api.swagger.Versioning v1|1.0");
                    swaggerUiOptions.SwaggerEndpoint("/swagger/v2/swagger.json","api.swagger.Versioning v2|2.0");

                    swaggerUiOptions.InjectJavascript("/js/inject.js");
                    swaggerUiOptions.UseRequestInterceptor(fn);
                });
            }

            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthorization();
            

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
            });
        }

基本上我去寻找是否可以解析版本的值 - 当它成为可能时,我将它添加到标题中。

可能有一些更优雅的方法来做到这一点,希望有人会来告诉我 - 但这是我自己提出的。

我的代码示例: https://github.com/figueiredorj/api.swagger

关于 Swashbuckle.AspNetCore 的旁注 - 它似乎从 6.0.7 开始工作