【西天取经】(骚操作)net core WebAPI生成ReDoc文档后支持多语言样例(x-code-samples)

【西天取经】(骚操作)net core WebAPI生成ReDoc文档后支持多语言样例(x-code-samples)

现在做的项目多是以WebAPI的方式对外提供功能的,配合像Vue这样的前端技术展示出页面、或者自己写的程序调用或者外部第三方公司写的程序调用。

程序员不仅需要写完接口的功能,还需要把这些接口功能对应的文档写出来,多数情况下程序员会直接通过工具来生成接口的文档,普遍使用的是:Swagger

.net core使用Swagger功能需要引用Swashbuckle.AspNetCore这个包以及它的子包。(也有用别的包来实现的)。我只介绍我的项目里面用到哪些包:

  <PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
  <PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.6.3" />
  <PackageReference Include="Swashbuckle.AspNetCore.Newtonsoft" Version="5.6.3" />
  <PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="5.6.3" />

其中Swashbuckle.AspNetCore.ReDoc这个包就是我这篇文章要介绍的内容。ReDoc是一个既美观又大方的展示页面(它使用React+TypeScript语言开发出来的,最终编译后会生成一个js文件和一个html文件),Swashbuckle.AspNetCore.ReDoc包里面已经包含编译之后的js和html文件,如图所示:

没用过ReDoc界面的人可能还是不清楚它到底长什么样子。

首先,看一下Swagger-UI的界面样子:(基本上都见过了)

然后,ReDoc的界面样子:(我要介绍的就是这个界面)

通常情况下,程序员会把Swagger-UI的界面留给自己或者内部使用,因为Swagger-UI可以发送请求测试接口的功能,也是入门必备的技能包;但是ReDoc更侧重于给外部第三方的客户使用,这两种展示方式我个人认为只是有用途上的区分而已。而 Knife4j 和 Swagger-UI 用途上我认为更接近。下图是Knife4j的界面(本文不介绍),我们给前端组的小伙伴提供接口文档用这个界面。

如果想把ReDoc文档变得更漂亮或者想加上公司的logo等等有定制需求时,就需要下载ReDoc源码自己改吧改吧了。我们目前就是自己稍微改了一下然后放到官网上去的。

ReDoc如果只是把上面这些接口的信息显示出来肯定是缺了点什么,到底缺什么呢?答案是:缺例子。第三方客户看到这些文档,又没有例子100%会关闭你的网页,因为没有人会花时间学习你的接口文档,除非你做的项目足够强大或者你所在的公司高大尚。但是往往像这样牛逼的公司提供出来的接口文档都会很全的,相反自己做的接口文档少这少那,又怎么会有人用你做的东西呢?

下面就来做一个带有多语言sampleRedoc文档,如图所示:

  • C#:

  •  Java:

 

  •  PHP:

 

  •  Python:

 

代码奉上:(前提是你的会Swagger,我这里只介绍ReDoc添加多语言sample代码)

1、.net core项目使用ReDoc:

/// <summary>
/// 加入ReDoc中间件
/// </summary>
/// <param name="app"></param>
/// <param name="environment"></param>
private void UseReDoc(IApplicationBuilder app, IWebHostEnvironment environment)
{
    app.UseSwagger(options => { options.RouteTemplate = "webapi/swagger/{documentName}/swagger.yaml"; options.SerializeAsV2 = true; });

    app.UseReDoc(option =>
    {
        option.RoutePrefix = "webapi";
        option.SpecUrl = $"/webapi/swagger/v1/swagger.yaml";
        option.DocumentTitle = "ReDoc多语言sample代码示例";
        option.ConfigObject = new Swashbuckle.AspNetCore.ReDoc.ConfigObject
        {
            NoAutoAuth = true,
            HideDownloadButton = true,
            HideLoading = false,
            HideHostname = true,
            RequiredPropsFirst = true,
            DisableSearch = true,
            NativeScrollbars = true,
        };
    });
}

2、设置ReDoc增加多语言的samples代码ReDoc就是从x-code-samples里面拿各种语言的sample代码

/// <summary>
/// 用来生成Swagger里面ReDoc多语言Sample例子。即:"x-code-samples"里面的内容
/// </summary>
public class XCodeSamplesOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        const string KEY = "x-code-samples";
        if (!operation.Extensions.ContainsKey(KEY))
        {
            var xCodeSamplesAttributes = context.MethodInfo
                                                .GetCustomAttributes(true)
                                                .OfType<XCodeSamplesAttribute>()  //自定义的Attribute
                                                ;
            if (xCodeSamplesAttributes == null || !xCodeSamplesAttributes.Any())
            {
                return;
            }

            OpenApiArray openApiArray = new OpenApiArray();
            foreach(var xCodeSamples in xCodeSamplesAttributes)
            {
                openApiArray.Add(new OpenApiObject
                   {
                       {"lang", new OpenApiString(xCodeSamples.Lang)},
                       {"source", new OpenApiString(xCodeSamples.Source, true)}
                   });
            }
            operation.Extensions.Add(KEY, openApiArray);
        }
    }
}

3、自定义XCodeSamplesAttribute,用来添加每种语言的sample代码:

/// <summary>
/// 用来生成Swagger里面ReDoc多语言Sample例子。即:"x-code-samples"里面的内容
/// </summary>
[System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = true)]
public class XCodeSamplesAttribute : Attribute
{
    /// <summary>
    /// 语言
    /// </summary>
    public string Lang { get; set; }
    /// <summary>
    /// 代码
    /// </summary>
    public string Source { get; set; }

    public XCodeSamplesAttribute(string lang, string source)
    {
        this.Lang = lang;
        this.Source = source;
    }
}

4、设置Swagger的IOperationFilter和ReDoc进行关联,关于Swagger里面的设置还有很多其他知识,我这里就不啰嗦了,百度、谷歌都能找得到。这里只介绍和多语言sample相关的代码部分:

/// <summary>
/// 注入Swagger服务
/// </summary>
/// <param name="services"></param>
private void AddSwagger(IServiceCollection services)
{
    //注册Swagger生成器
    services.AddSwaggerGen(option =>
    {
    ...
       option.OperationFilter<XCodeSamplesOperationFilter>();
    ...
    }
}

5、给Controller里面的某一个Action上添加多语言的sample代码,使用自定义的XCodeSamplesAttribute(下面的代码看着有点丑)。

/// <summary>
/// 获取单个用户信息
/// </summary>
/// <param name="userId">用户ID</param>
/// <returns></returns>
[HttpGet("{user_id}")]
[XCodeSamples(lang: "C#", source: @"
var client = new RestClient(""https://example.com/webapi/a2/users/{user_id}"");
client.Timeout = -1;
var request = new RestRequest(Method.GET);
request.AddHeader(""webapi_token"", ""your secret key"");
IRestResponse response = client.Execute(request);
Console.WriteLine(response.Content);")

 , XCodeSamples(lang: "Java", source: @"
OkHttpClient client = new OkHttpClient().newBuilder().build();
Request request = new Request.Builder()
                     .url(""https://example.com/webapi/a2/users/{user_id}"")
                     .method(""GET"", null)
                     .addHeader(""webapi_token"", ""your secret key"")
                     .build();
Response response = client.newCall(request).execute();")

 , XCodeSamples(lang: "PHP", source: @"
<?php

$curl = curl_init();

curl_setopt_array($curl, array(
CURLOPT_URL => ""https://example.com/webapi/a2/users/%7Buser_id%7D"",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => """",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => ""GET"",
CURLOPT_HTTPHEADER => array(
""webapi_token: your secret key""
),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;")

 , XCodeSamples(lang: "Python", source: @"
import http.client
import mimetypes

conn = http.client.HTTPSConnection(""example.com"", 443)
payload = ''
headers = {
'webapi_token': 'your secret key'
}
conn.request(""GET"", ""/webapi/a2/users/{user_id}"", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode(""utf-8""))")
]
public JsonModel<ApiUserInfoModelOpenAPI> GetUser([FromRoute(Name = "user_id")] long userId)
{
    ...
}

好了,终于完工了,这回你的ReDoc文档看起来就很全面了。

如果你不知道其他语言的代码怎么写出来的,我这里介绍一个简单的方法,使用Postman可以帮你轻松完成,我拿一个URL举例来介绍,如图:

从下图里找到你需要添加的语言,然后直接复制右面的代码就可以了。注意:往C#里面粘贴下面的代码时,因为字符串里面会有双引号,和C#里面的@符号有冲突,用两个双引号就可以解决了。

 

希望每一个对外提供接口的项目,都能给你的客户提供更全更好的接口文档。

posted @ 2020-10-30 16:49  八_戒  阅读(1315)  评论(1编辑  收藏  举报