K8S APIServer依赖的go-restful WebService框架的简单使用

在 K8S 的 APIServer 的代码中,依赖了一个叫做 go-restful 的库来构建 HTTP 的 API。 在学习 K8S 的代码过程中,我们要对这个库做些了解,这样才能更加方便地知道 APIServer 的 Restful 服务是如何构建的。

这个项目在 Github 上面的地址是:

https://github.com/emicklei/go-restful 。

我们也很容易地找到了作者的一篇介绍使用方法的博客。

帖子的地址在:

http://ernestmicklei.com/2012/11/go-restful-first-working-example/

这里我们将它简单翻译一下,帮助大家学习。下面的内容是译文。

在前面的一个帖子里面,我介绍了用 Google 的 Go 语言开发的,用来构建 REST 风格 WebService 的包 go-restful 的设计。 今天,我完成了这个包的实现,包含如下的功能:

使用 Route 来创建 WebService,Route 是 HTTP Request 到 Go 函数的映射。

每个 Route 都需要的信息包括 HTTP 请求方法(GET,POST,...),URL 路径(/users),MimeType以及其绑定的处理函数。

处理函数的输入包括一个 Request 和一个 Response。

Request 对象用来获取 Path 和 Query参数,Headers以及 Request Body(XML,JSON,...)。

Response 对象用来设置 Status,Headers,以及 Response Body

Request 和 Response 对象都可以使用标准库来在对象和XML或JSON之间进行转换。

我们可以使用一个简单的例子来演示上面的过程。一个用来对User 对象进行 CRUD 操作的 WebService。 我们首先在一个 userservice 目录里面创建一个 userservice.go 文件。

packageuserserviceimport("github.com/emicklei/go-restful""log")typeUserstruct{ Id, Namestring}

User 类型代表我们要操作的对象。

文件中的下一个部分就是 WebService 的 API 定义。这些 API 是一组Route对象的集合,这些Route定义了如何将进来的 HTTP 请求映射到对应的处理函数。

funcNew() *restful.WebService{service:=new(restful.WebService) service.Path("/users").Consumes(restful.MIME_XML, restful.MIME_JSON).Produces(restful.MIME_XML, restful.MIME_JSON) service.Route(service.GET("/").To(FindUser)) service.Route(service.POST("").To(UpdateUser)) service.Route(service.PUT("/").To(CreateUser)) service.Route(service.DELETE("/").To(RemoveUser)) return service}

首先,使用一个 root URL 来初始化所有路径的 service,定义每个 Route 可以接收的MIME类型,以及可以响应的MIME类型。当然这个也可以针对每个Route单独指定。然后,service 指定它可以提供哪些路径。这里的函数调用 是 的简单写法,这个方法调用创建一个 RouteBuilder 对象。然后使用这个 RouteBuilder 对象指定对应的处理函数。

下面,就是定义每个 Route 的处理函数了。

funcFindUser(request*restful.Request,response*restful.Response) {id:= request.PathParameter("user-id") // here you would fetch user from some persistence system usr := &Userresponse.WriteEntity(usr)}

Route 的处理函数的方法声明都一样,包含一个 Restful 的 Request 和 Response,两个一对。 Request 是 http Request 对象的封装,提供了一些方便的方法。Response 是对 http ResponseWriter 的封装。这种设计方式可以将底层的 HTTP 结构开放给开发者,同时也为开发者提供了一些通用的 Restful 函数,例如 WriteEntity。WriteEntity 函数会检查请求的 Accept 头部来决定 response 的 Content-Type 头部,同时也决定了使用那种方法来序列化对象(这里就是 User 对象)。

userservice.go 文件的其他内容就是剩下的Route处理函数的定义。

funcUpdateUser(request *restful.Request, response *restful.Response){ usr :=new(User) err := request.ReadEntity(&usr)// here you would update the user with some persistence systemiferr ==nil{ response.WriteEntity(usr) }else{ response.WriteError(http.StatusInternalServerError,err) }}funcCreateUser(request *restful.Request, response *restful.Response){ usr := User err := request.ReadEntity(&usr)// here you would create the user with some persistence systemiferr ==nil{ response.WriteEntity(usr) }else{ response.WriteError(http.StatusInternalServerError,err) }}funcRemoveUser(request *restful.Request, response *restful.Response){// here you would delete the user from some persistence system}

现在,我们已经完成了 UserService 的定义和实现。下面的代码段演示了如何在一个应用中使用这个 service。

packagemainimport("github.com/emicklei/go-restful""log""net/http""userservice")funcmain(){ restful.Add(userservice.New()) log.Fatal(http.ListenAndServe(":8080",nil))}

服务启动之后,我们可以利用下面的方法测试:

默认的请求

$ curl http://localhost:8080/users/1212John Doe

带 Accpet 头部的请求

$ curl http://localhost:9090/users/12-H 'Accept: application/json'{"Id":"12","Name":"John Doe"}

新建一个User对象

$ curl http://localhost:9090/users -X POST -d '{"Id":"32","Name":"jemygraw"}' -H 'Content-Type: application/json'32jemygraw

新的一个User对象,要求返回JSON。

$ curlhttp://localhost:9090/users-X POST -d'{"Id":"32","Name":"jemygraw"}'-H'Content-Type: application/json'-H'Accept: application/json'{"Id":"32","Name":"jemygraw"}

译者:

本文永久保存地址为:

https://github.com/jemygraw/TechDoc/blob/master/Go%E5%BA%93%E5%AD%A6%E4%B9%A0/2018-09-14%20k8s%20%E4%BE%9D%E8%B5%96%E5%BA%93%E4%B8%AD%E7%9A%84go-restful%E6%A1%86%E6%9E%B6.md

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180917B0P9GD00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券