随着见闻的逐渐加深,接触或者了解过一些其他的优秀的文档编写工具,由于未深入研究过,所以,仅仅在这里进行简单的列举:
 
swagger特点 swagger是我见过唯一还算将就的一个API文档制作与展示工具,其实最终都没让我找到一款完美的API文档编写工具。
swagger优点:
只针对API,而不针对特定的语言的API,很多自动生成API的工具基本都是只针对特定的API的 
支持Json和yaml来编写API文档,并且支持导出为json、yaml、markdown等格式 
如果编写好了API了,可以自动生成相应的SDK,没错,可能你的API接口代码还没有开始写,它就能帮你制作相应的SDK了,而且支持几乎所有主流编程语言的SDK 
支持自动生成大量主流编程语言/框架的server端 
界面清晰,无论是editor的实时展示还是ui的展示都十分人性化,其他的API编写工具基本上都做不到这一点,如果自己仅仅用markdown来编写,又要纠结该如何展现,十分痛苦。 
官网有直接的demo,甚至都可以不用自己搞一套服务器 
 
swagger缺点:
貌似无法更改主题 
中英文的文档都比较少,其主要原因应该是官网的文档本身就不完善,只有针对不同模块儿的介绍,却没有针对具体用户的文档 
yaml文件只能和API项目本身放在一起,这一点暂时还不知道有什么解决方案 
 
 
其他的API文档编写工具 Apizza 
外观模仿postman,但是只有网页版,必须谷歌浏览器并且必须安装插件,不开源,不能确定以后是否收费 
由于外观模仿postman,所以ui上还是不大满意 
能够自定义环境变量,并且可以不同的环境不同的环境变量 
拥有团队协作功能,并且有一定的权限管理功能 
可直接在接口处编写文档,并且能够导出HTML文档,导入Postman Json或者Swagger Json 
偶尔会有缓存没有清理的问题 
没有mock server的功能 
 
APIBlueprint 
自定义markdown语法,用markdown来编写 
由于自定义了太多的语法,个人认为最后的markdown文件非常混乱,因为很多时候多空格多空行不会影响结果 
也能生成mock server 
界面美观,但是不是很直观 
能够导出markdown和yaml 
 
RAP 
淘宝出品,Github上start数4000+ 
可以在公司内部搭建,不同的团队都可以在上面创建团队文档和分组 
不能定义GET、POST、PUT、DELETE之外的请求 
Model不能共享,写了一个地方另外一个地方还要写 
只能定义200的响应,无法定义请求头、请求格式和相应格式 
网页直接用js生成mock数据 
界面有些地方好看,有些地方很丑。。。 
只能导出为没有样式的html 
 
安装与使用 我这里仅仅是简单地使用了swagger其中一项功能,即用swagger-editor编写API文档,生成yaml文件,然后通过swagger-ui来进行展示。由于仅仅是我本地搭建,所以两个组件都使用的docker搭建:
1 2 docker run -i -t -p 8080:8080 --name swagger-ui -d swaggerapi/swagger-ui docker run -i -t -p 8081:8080 --name swagger-editor -d swaggerapi/swagger-editor 
 
然后访问http://127.0.0.1:8080即可访问swagger-ui,http://127.0.0.1:8081即可访问swagger-editor了。
接下来就是问题最多的如何使用的问题了,在第一次使用过程中,有诸多的问题需要解决,当然,主要的就是CROS问题。
CROS跨域问题 在使用editor的时候你可能会用到Try this operation功能,即把接口定义好,想要直接进行请求调试,填上参数后网页可能会在js报这样的错误: XMLHttpRequest cannot load http://api.haofly.net/projects/test. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1:8081' is therefore not allowed access.这就是传说中的CROS问题了,原因是后台程序为了安全默认关闭了跨域的请求,这时候有两种方式,一种是修改nginx,使其能直接通过,一种是修改程序,使其在返回请求的时候能够附带加上CROS的信息。例如,我在Laravel下面,可以添加这样一个中间件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 namespace  App \Http \Middleware ;use  Closure ;class  EnableCrossRequestMiddleware  {    public  function  handle ($request , Closure  $next  )      {        $response  = $next ($request );         $response ->headers->set ('Access-Control-Allow-Origin' , 'http://127.0.0.1:8081' );         $response ->headers->set ('Access-Control-Allow-Headers' , 'Origin, Content-Type, Cookie, Accept, Authorization, Application, X-Requested-With' );         $response ->headers->set ('Access-Control-Allow-Methods' , 'GET, POST, PATCH, PUT, OPTIONS, DELETE' );         $response ->headers->set ('Access-Control-Allow-Credentials' , 'true' );         return  $response ;     } } 
 
这样,后台程序就允许127.0.0.1:8081这个域进行跨域访问了。
OAuth2认证问题 swagger是无法自定义请求头的,这一点,其Github上面的Issues有解释,现在已经忘了,但是针对特殊的头,它还是会有特定的办法,比如OAuth2的认证,它本身就是支持的。
首先,需要在yaml文件中定义这样一些字段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 securityDefinitions: 	  Bearer:      type:  apiKey      name:  Authorization      in:  header       /projects/{projectName}:   get:      summary:  获取指定项目名的项目信息      security: 			       -  Bearer:  []     parameters:        -  name:  projectName          in:  path          type:  string          description:  项目名          required:  true      responses:        200:          description:  项目信息  
 
之后,swagger-editor实时预览会出现Security Authentication的安全认证,可以将token填入其中,然后在Try this operation的时候勾选上Security->Bearer即可,可以看到自动在请求头中添加了Authorization字段了。
Swagger-ui获取解析文件的问题 其实Swagger-ui仅仅是接收一个url,通过该url获取yaml文件,然后负责解析而已。但是,这里的坑也是不少的。
首先,在swagger-ui中,默认发送的请求,是针对那个yaml文件所在的地方,这是十分坑的地方,所以yaml文件必须放在相应的API项目的文件里。暂时没有发现其他的解决方案。
其次,给定的url并不直接指向该文件的静态路径,而是需要添加CROS的响应头,所以不能直接用nginx的静态文件来处理。哎,所以基本上要做到的是,你直接访问那个url的时候,浏览器会弹出下载狂而不是直接显示那个文件的内容。
文档编写语法 虽然json比yaml好用,但是在这里我还是觉得yaml更好看,更方便,所以我这里都用yaml来用,并且如果要json,它都是可以互相转换的,语法都一样。以下来自官方文档 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 swagger:  '2.0' 						info:   title:  文档标题    description:   描述    version:  "v1.0" 					   termsOfService:  "" 				   contact: 							   	name:  "" 						   	url:  "" 							   	email:  "" 						   license: 							   	name:  "" 						   	url:  "" 							 host:  api.haofly.net 				basePath:  / 							schemes: 							  -  http    -  https     securityDefinitions: 				  api_key:      type:  apiKey      name:  Authorization 				     in:  header 						   OauthSecurity: 					     type:  oauth2      flow:  accessCode 				     authorizationUrl:  'https://oauth.simple.api/authorization'      tokenUrl:  'https://oauth.simple.api/token'      scopes:        admin:  Admin  scope        user:  User  scope        media:  Media  scope    auth:    	type:  oauth2    	description:  "" 					   	authorizationUrl:  http://haofly.net/api/oauth/    	name:  Authorization 				   	tokenUrl:    	flow:  implicit 					   	scopes:    	  write:post:  修改文件    	  read:post:  读取文章    	   security: 							  auth:      -  write:pets      -  read:pets    	   consumes: 							  -  application/json 				   -  application/vnd.github.v3+json     produces: 							  -  application/vnd.knight.v1+json 	   -  text/plain;  charset=utf-8  tags: 								  -  name:  post 	     description:  关于post的接口       externalDocs:   description:  find  more  info  here    url:  https://haofly.net       paths: 								  /projects/{projectName}: 			     get:        tags: 							         -  post 	       summary:  接口描述 				        description:  					       externalDocs: 					       	description:        	url:        operationId:  "" 				       consumes:  [string ]			       produces:  [string ]			       schemes:  [string ]				       deprecated:  false 				       security: 						         -  auth:           	-  write:post          	-  read:  read        parameters: 					         -  name:  projectName 			           in:  path 					           type:  string 				           allowEmptyValue:  boolean 			           description:  项目名 		             required:  true 			           default:  * 				           maximum:  number 			           exclusiveMaximum:  boolean 	           minimum:  number 			           exclusiveMinimum:  boolean            maxLength:  integer 		           minLength:  integer            enum:  [* ]					           items: 					         -  $ref:  "#/parameters/uuidParam" 	       responses: 					         200: 						           description:  Success 		           schema: 					           	$ref:  '#/definitions/ProjectDataResponse' 	              /another: 	   	  responses:    	  	200:    	  		description:    	  		schema:    	  		  type:  object    	  		  properitis:    	  		  	data:    	  		  		$ref:  '#/definitions/User' 	    definitions: 			  Product: 				     type:  object 		     properties: 			       product_id: 		         type:  integer 	         description:  	 	  product_name:  	  	type:  string  	  	description:     ProjectDataResponse:    	type:  object    	properties:    		data:    			$ref:  '#/definitions/ProjectResponse' 	 parameters: 				  limitParam:      name:  limit      in:  query      description:  max  records  to  return      required:  true      type:  integer      format:  int32  responses: 				  NotFound:      description:  Entity  not  found. 	 	 
 
支持的数据类型 1 2 3 4 5 6 7 8 9 10 11 integer: int32 long: int64 float double string byte binary boolean date dateTime password