现在做的项目多是以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%会关闭你的网页,因为没有人会花时间学习你的接口文档,除非你做的项目足够强大或者你所在的公司高大尚。但是往往像这样牛逼的公司提供出来的接口文档都会很全的,相反自己做的接口文档少这少那,又怎么会有人用你做的东西呢?
下面就来做一个带有多语言的sample的Redoc文档,如图所示:
C#:
Java:
PHP:
Python:
代码奉上:(前提是你的会Swagger,我这里只介绍ReDoc添加多语言sample代码)
1、.net core项目使用ReDoc:
/// /// 加入ReDoc中间件/// /// /// 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代码:
/// /// 用来生成Swagger里面ReDoc多语言Sample例子。即:"x-code-samples"里面的内容/// 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() //自定义的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代码:
/// /// 用来生成Swagger里面ReDoc多语言Sample例子。即:"x-code-samples"里面的内容/// [System.AttributeUsage(System.AttributeTargets.Method, AllowMultiple = true)]public class XCodeSamplesAttribute : Attribute{ /// /// 语言 /// public string Lang { get; set; } /// /// 代码 /// public string Source { get; set; } public XCodeSamplesAttribute(string lang, string source) { this.Lang = lang; this.Source = source; }}
4、设置Swagger和ReDoc的IOperationFilter进行关联,关于Swagger里面的设置还有很多其他知识,我这里就不啰嗦了,百度、谷歌都能找得到。这里只介绍和多语言sample相关的代码部分:
/// /// 注入Swagger服务/// /// private void AddSwagger(IServiceCollection services){ //注册Swagger生成器 services.AddSwaggerGen(option => { ... option.OperationFilter(); ... }}
5、给Controller里面的某一个Action上添加多语言的sample代码,使用自定义的XCodeSamplesAttribute(下面的代码看着有点丑)。
/// /// 获取单个用户信息/// /// "userId">用户ID/// [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.clientimport mimetypesconn = 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 GetUser([FromRoute(Name = "user_id")] long userId){ ...}
好了,终于完工了,这回你的ReDoc文档看起来就很全面了。
如果你不知道其他语言的代码怎么写出来的,我这里介绍一个简单的方法,使用Postman可以帮你轻松完成,我拿一个URL举例来介绍,如图:
从下图里找到你需要添加的语言,然后直接复制后面的代码就可以了。注意:往C#里面粘贴下面的代码时,因为字符串里面会有双引号,和C#里面的@符号有冲突,用两个双引号就可以解决了。
希望每一个对外提供接口的项目,都能给你的客户提供更全更好的接口文档。