歡迎光臨
每天分享高質量文章

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 的設計。 今天,我完成了這個包的實現,包含如下的功能:

  1. 使用 Route 來建立 WebService,Route 是 HTTP Request 到 Go 函式的對映。

  2. 每個 Route 都需要的資訊包括 HTTP 請求方法(GET,POST,…),URL 路徑(/users),MimeType以及其系結的處理函式。

  3. 處理函式的輸入包括一個 Request 和一個 Response。

  4. Request 物件用來獲取 Path 和 Query引數,Headers以及 Request Body(XML,JSON,…)。

  5. Response 物件用來設定 Status,Headers,以及 Response Body

  6. Request 和 Response 物件都可以使用標準庫來在物件和XML或JSON之間進行轉換。

我們可以使用一個簡單的例子來演示上面的過程。一個用來對User 物件進行 CRUD 操作的 WebService。 我們首先在一個 userservice 目錄裡面建立一個 userservice.go 檔案。

package userserviceimport (    "github.com/emicklei/go-restful"    "log")type User struct {    Id, Name string}

User 型別代表我們要操作的物件。

檔案中的下一個部分就是 WebService 的 API 定義。這些 API 是一組Route物件的集合,這些Route定義瞭如何將進來的 HTTP 請求對映到對應的處理函式。

func New() *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("/{user-id}").To(FindUser))    service.Route(service.POST("").To(UpdateUser))    service.Route(service.PUT("/{user-id}").To(CreateUser))    service.Route(service.DELETE("/{user-id}").To(RemoveUser))    return service }

首先,使用一個 root URL 來初始化所有路徑的 service,定義每個 Route 可以接收的MIME型別,以及可以響應的MIME型別。當然這個也可以針對每個Route單獨指定。然後,service 指定它可以提供哪些路徑。這裡的函式呼叫GET("/{user-id}") 是 Method("GET").Path("/{user-id}") 的簡單寫法,這個方法呼叫建立一個 RouteBuilder 物件。然後使用這個 RouteBuilder 物件指定對應的處理函式。

下麵,就是定義每個 Route 的處理函式了。

func FindUser(request *restful.Request, response *restful.Response) {    id := request.PathParameter("user-id")    // here you would fetch user from some persistence system    usr := &User;{Id: id, Name: "John Doe"}    response.WriteEntity(usr) }

Route 的處理函式的方法宣告都一樣,包含一個 Restful 的 Request 和 Response,兩個一對。 Request 是 http Request 物件的封裝,提供了一些方便的方法。Response 是對 http ResponseWriter 的封裝。這種設計方式可以將底層的 HTTP 結構開放給開發者,同時也為開發者提供了一些通用的 Restful 函式,例如 WriteEntity。WriteEntity 函式會檢查請求的 Accept 頭部來決定 response 的 Content-Type 頭部,同時也決定了使用那種方法來序列化物件(這裡就是 User 物件)。

userservice.go 檔案的其他內容就是剩下的Route處理函式的定義。

func UpdateUser(request *restful.Request, response *restful.Response) {    usr := new(User)    err := request.ReadEntity(&usr;)    // here you would update the user with some persistence system    if err == nil {        response.WriteEntity(usr)    } else {        response.WriteError(http.StatusInternalServerError,err)    } }func CreateUser(request *restful.Request, response *restful.Response) {    usr := User{Id: request.PathParameter("user-id")}    err := request.ReadEntity(&usr;)    // here you would create the user with some persistence system    if err == nil {        response.WriteEntity(usr)    } else {        response.WriteError(http.StatusInternalServerError,err)    } }func RemoveUser(request *restful.Request, response *restful.Response) {    // here you would delete the user from some persistence system}

現在,我們已經完成了 UserService 的定義和實現。下麵的程式碼段演示瞭如何在一個應用中使用這個 service。

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

服務啟動之後,我們可以利用下麵的方法測試:

  1. 預設的請求

$ curl http://localhost:8080/users/12xml version="1.0" encoding="UTF-8"?> <User>  <Id>12Id>  <Name>John DoeName>

User>

  1. 帶 Accpet 頭部的請求

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

  1. 新建一個User物件

$ curl http://localhost:9090/users -X POST -d '{"Id":"32","Name":"jemygraw"}' -H 'Content-Type: application/json'xml version="1.0" encoding="UTF-8"?> <User>  <Id>32Id>  <Name>jemygrawName>

User>

  1. 新的一個User物件,要求傳回JSON。

$ curl http://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

贊(0)

分享創造快樂