Goweb如何一步步整合swaggerui我们可以官方提供的方式:https:github。comgoswaggergoswagger,主要方式是:1、写我们的go程序,2、让swagger工具扫描我们的go文件,3、生成swagger注释。 我们先说存在的问题:1、注释本地生成,会因为swagger版本不一致出现问题,出现各种git冲突,需要采用打包编译时去执行生成。2、违背了编程的方式。3、为什么Java的swagger那么火,是因为和springboot完美整合,那么Spring解决的其实就是ioc的控制,所以go的web也不需要程序去控制,路由,输入,输出,所以我们需要这么做。前期准备1、需要实现SpringBoot的controoler接口的方式 大致需求:1、拿到路由,2、拿到请求、响应(这个是go所有web框架做不到的,所以需要转变思想)RestControllerpublicclassUserController{AutowiredprivateUserRepositoryrepository;PostMapping(save)publicUserecho(UserInfoDtoinfo){returnrepository。save(User。builder()。id(info。getId())。userName(info。getName())。build());}}2、转变思想 这个反射调用的框架,我写了一个,希望大家多多提交bug,因为反射本身缺陷很多:https:github。comAnthonyDonggorpcvar(userServiceservice。NewUserService())funcuserRoute(eengines。Engine){g:e。Group(report)g。POST(benchmark,http。NewHandlerFunc(userService。BenchMark))}定义context。Context(必不可少),类似于Java的ThreadLocalrequestdto。BenchmarkRequest请求dto。BenchmarkResponse详情error由于go本身没有throw,所以需要显示的申明后期考虑加入web模块,但是目前主流web框架都是依赖于ctx向下传递,所以go和Java这点不一样(目前不考虑,可以考虑使用gin的context),虽然Springmvc中也可以接受httprequest,httpresponse但是由于它的bind,用户都不care了(这就是申明式编程的好处)typeUserServiceinterface{BenchMark(ctxcontext。Context,requestdto。BenchmarkRequest)(dto。BenchmarkResponse,error)} 实现了这个,那么我们就开始吧,因为这些要求的,我们都可以拿到。3、定义强路由 1、因为go本身并没有方法级别的注解,如果我们可以在每个interface上申明接口,在每个方法上申明路由pathuserservicetypeUserServiceinterface{pathbenchmarkmethodgetBenchMark(ctxcontext。Context,requestdto。BenchmarkRequest)(dto。BenchmarkResponse,cerror。Cerror)} 如果这样子,那么对于go的开发者特别不友好 2、所有采用func注册的方式 可以在接口后面指定get其他g。POST(benchmark,http。NewHandlerFunc(userService。BenchMark),op。Get()) 目前采用的这种方式:1、可以显示的声明,符合go开发者的习惯,2、可以不用扫描go文件(springboot采用的这种方式)整合swagger客户端找到swagger的web端资源包,然后将其都暴露出去,接下来核心就是swagger。json了。 资源在我的这个项目的swagger里面https:github。comAnthonyDonggorpc,后期会考虑静态资源使用api调用的方式(转发的方式),目前是借助工具写在了go文件里:https:github。comaurthgobindata,这个工具很nice,可以讲文件写入到go文件里,以二进制的形式,我们知道go是不可以打包成jar包的,只有二进制文件,静态资源是一个很难受的事情,所以需要这么做。const(jsjscsscsshtmlhtmlbytebytejsonjson)funcaddSwagger(pathstring,typestring)func(writerhttp。ResponseWriter,requesthttp。Request){returnfunc(writerhttp。ResponseWriter,requesthttp。Request){body,:swagger。Asset(path)switchtype{casejs:writer。Header()。Set(contenttype,applicationjavascript)casecss:writer。Header()。Set(contenttype,textcss)casejson:writer。Header()。Set(contenttype,applicationjson)}iftypebyte{fmt。Fprint(writer,body)return}fmt。Fprint(writer,string(body))}}funcaddSwaggerRouter(pathstring,typestring){http。HandleFunc(path,addSwagger(path,type))}funcmain(){swagger内置服务端需要的东西addSwaggerRouter(swaggeruiabsolutepath。js,js)addSwaggerRouter(swaggeruifavicon16x16。png,byte)addSwaggerRouter(swaggeruifavicon32x32。png,byte)addSwaggerRouter(swaggeruiindex。html,html)addSwaggerRouter(swaggeruiindex。js,js)addSwaggerRouter(swaggeruioauth2redirect。html,html)addSwaggerRouter(swaggeruipackage。json,json)addSwaggerRouter(swaggeruiswaggeruibundle。js,js)addSwaggerRouter(swaggeruiswaggeruibundle。js。map,html)addSwaggerRouter(swaggeruiswaggeruistandalonepreset。js,js)addSwaggerRouter(swaggeruiswaggeruistandalonepreset。js。map,html)addSwaggerRouter(swaggeruiswaggerui。css,css)addSwaggerRouter(swaggeruiswaggerui。css。map,html)addSwaggerRouter(swaggeruiswaggerui。js,js)addSwaggerRouter(swaggeruiswaggerui。js。map,html)http。HandleFunc(swagger。json,func(writerhttp。ResponseWriter,requesthttp。Request){writer。Header()。Set(contenttype,applicationjson)fmt。Fprintf(writer,doc)})http。ListenAndServe(:8888,nil)}swaggerjson 这个文件来自于faygo,swagger核心是一个api接口,类似于下面这个样子{swagger:2。0,info:{description:SpringSwaager2RESTAPI,version:V1,title:RESTAPI,contact:{name:anthony,url:https:github。comAnthonyDong,email:574986060qq。com},license:{name:TheApacheLicense,url:https:opensource。orglicensesMIT}},host:localhost:8888,basePath:,tags:〔{name:usercontroller,description:UserController}〕,paths:{find{id}:{get:{tags:〔usercontroller〕,summary:find,operationId:findUsingGET,produces:〔〕,parameters:〔{name:id,in:path,description:id,required:true,type:integer,format:int64}〕,responses:{200:{description:OK,schema:{ref:definitionsUser}}},deprecated:false}},save{name}:{get:{tags:〔usercontroller〕,summary:echo,operationId:echoUsingGET,produces:〔〕,parameters:〔{name:name,in:path,description:name,required:true,type:string}〕,responses:{200:{description:OK,schema:{ref:definitionsUser}}},deprecated:false}}},definitions:{User:{type:object,properties:{id:{type:integer,format:int64},userName:{type:string}},title:User}}}一步步写doc 下面是swaggerdoc的大致结构,我们必须将我们的api注入进去doc:swagger。Swagger{Version:swagger。Version,Info:swagger。Info{Title:RESTAPI,Contact:swagger。Contact{Email:fanhaodong516gmail。com,},License:swagger。License{Name:TheApacheLicense,Url:https:opensource。orglicensesMIT,},},Host:localhost:8888,BasePath:,Tags:〔〕swagger。Tag{},tagPaths:map〔string〕map〔string〕swagger。Opera{},所有的api路由Definitions:map〔string〕swagger。Definition{},定义dto对象}tag是什么 usercontroller就是一个tag,对于go来说一般是group可以定义为一个controller TagobjectTagstruct{Namestringjson:name一个标签:usercontrollerDescriptionstringjson:description一个des:usercontroller} 同时所有的path都可以指定多个tagOperastruct{Tags〔〕stringjson:tags这里是tagSummarystringjson:summaryDescriptionstringjson:descriptionOperationIdstringjson:operationIdConsumes〔〕stringjson:consumes,omitemptyProduces〔〕stringjson:produces,omitemptyParameters〔〕Parameterjson:parameters,omitemptyResponsesmap〔string〕Respjson:responses{httpcode:resp}Security〔〕map〔string〕〔〕stringjson:security,omitempty}认识path 这就是一个pathPathsmap〔string〕map〔string〕Operajson:paths,omitempty 结构是个两级mapsave:{post:{tags:〔usercontroller〕,summary:echo,operationId:echoUsingPOST,consumes:〔请求类型applicationjson〕,produces:〔响应类型〕,parameters:〔核心关注的点,如果多级别{name:id,字段描述in:query,查询required:false,是否强需求,可以借助于binding,也就是go的Validator(https:github。comgoplaygroundvalidator)type:integer,类型format:int64真实类型(go类型)},{name:name,in:query,required:false,type:string},{name:user。id,in:query,required:false,type:integer,format:int64},{name:user。userName,in:query,required:false,type:string}〕,responses:{200:{状态吗description:OK,响应描述schema:{ref:definitionsUser指定路由:(nice,所以我们的dto全部放到modle里)}}},deprecated:false}},总结 通过以上,我们可以get到,确实是不是特别难,是有一定规律的,那么接下来,我们就可以开始设计框架了。