参考
https://www.jianshu.com/p/4724fd7084cb
https://blog.youkuaiyun.com/Daniel_greenspan/article/details/78624725
go-restful 框架中最基础的几个概念包括: route, webservice, container。
route
route是http server的基本概念,是指一条http请求的URL, 根据此URL来确定那个函数为其服务。 go-restful中的route也是一样的,不过代码实现的时候跟准确的说法是注册路由。路由包含两种,RouterJSR311和CurlyRouter, CurlyRoute是base于routerJSR311的,但是支持正则表达式和动态参数,更加轻量化。
CurlyRouter在设定式包含:请求路径(URL Path),输入输出类型(JSON/YAML),请求对应的处理函数, 请求的参数,文档描述以及对应的回掉函数restful.RouteFunction,响应内容类型(Accept)等。
webservice
webservice实际上是一组route的集合。这组route拥有相同的rootpath或者base path,拥有相同的输入输出格式,基本一致的请求数据类型等一些通用的属性,举例说明:User为例,webservice是以/user/为基础路径的一个route集合,其下列的请求都是请求route相关操作的route。
换一种说法是将一组相关性非常强的request URL封装成为一个webserviice。举个例子来说明我们在公司开发过程中有项目信息和用户信息; 这样项目可以作为一个webservice, 用户可以作为另一个webservice。
webservice只是一组route的集合,其必须加入到container中才能够生效。
Container
Container 在http的角度就成为一个Server, 其包含一组webservice, 一个serveMUx,以及对应的routeselect负责请求派发。
三者之间的关系
一个container实际上是对外提供的一个(从http的基本角度看)http Server; 一个container里面可以有很多个webservice, 一个webservice可以看做是一组对象的服务,是一个种类的服务请求的一个合集或者看成是子服务; 一个 route则是单个请求的路由,一个webservice包括一组route,这一组路由有相同的base路径。其三者的相互关系如下图:
安装
go get -u -v github.com/emicklei/go-restful
go get -u -v github.com/emicklei/go-restful-swagger12
失败
去网站 上下载,解压如下
https://github.com/emicklei/go-restful
https://github.com/emicklei/go-restful-swagger12
执行go install
go install github.com/emicklei/go-restful
go install github.com/emicklei/go-restful-swagger12
package main
import (
"github.com/emicklei/go-restful"
"github.com/emicklei/go-restful-swagger12"
"io"
"log"
"net/http"
)
func main(){
wsContainer := restful.NewContainer()
// 跨域过滤器
cors := restful.CrossOriginResourceSharing{
ExposeHeaders: []string{"X-My-Header"},
AllowedHeaders: []string{"Content-Type", "Accept"},
AllowedMethods: []string{"GET", "POST"},
CookiesAllowed: false,
Container: wsContainer}
wsContainer.Filter(cors.Filter)
// Add container filter to respond to OPTIONS
wsContainer.Filter(wsContainer.OPTIONSFilter)
config := swagger.Config{
WebServices: restful.DefaultContainer.RegisteredWebServices(), // you control what services are visible
WebServicesUrl: "http://localhost:8080",
ApiPath: "/apidocs.json",
ApiVersion: "V1.0",
// Optionally, specify where the UI is located
SwaggerPath: "/apidocs/",
SwaggerFilePath: "D:/gowork/src/doublegao/experiment/restful/dist"}
swagger.RegisterSwaggerService(config, wsContainer)
//swagger.InstallSwaggerService(config)
u := UserResource{}
u.RegisterTo(wsContainer)
log.Print("start listening on localhost:8080")
server := &http.Server{Addr: ":8080", Handler: wsContainer}
defer server.Close()
log.Fatal(server.ListenAndServe())
}
type UserResource struct{}
func (u UserResource) RegisterTo(container *restful.Container) {
ws := new(restful.WebService)
//设置匹配的schema和路径
ws.Path("/user").Consumes("*/*").Produces("*/*")
//设置不同method对应的方法,参数以及参数描述和类型
//参数:分为路径上的参数,query层面的参数,Header中的参数
ws.Route(ws.GET("/{id}").
To(u.result).
Doc("方法描述:获取用户").
Param(ws.PathParameter("id", "参数描述:用户ID").DataType("string")).
Param(ws.QueryParameter("name", "用户名称").DataType("string")).
Param(ws.HeaderParameter("token", "访问令牌").DataType("string")).
Do(returns200, returns500))
ws.Route(ws.POST("").To(u.result))
ws.Route(ws.PUT("/{id}").To(u.result))
ws.Route(ws.DELETE("/{id}").To(u.result))
container.Add(ws)
}
func (UserResource) SwaggerDoc() map[string]string {
return map[string]string{
"": "Address doc",//空表示结构本省的描述
"country": "Country doc",
"postcode": "PostCode doc",
}
}
func (u UserResource) result(request *restful.Request, response *restful.Response) {
io.WriteString(response.ResponseWriter, "this would be a normal response")
}
func returns200(b *restful.RouteBuilder) {
b.Returns(http.StatusOK, "OK", "success")
}
func returns500(b *restful.RouteBuilder) {
b.Returns(http.StatusInternalServerError, "Bummer, something went wrong", nil)
}
//post http://localhost:8080/user