Golang:go-restful庫使用手冊

Golang:go-restful庫使用手冊

  • 2019.4.1
  • 版權聲明:本文爲博主chszs的原創文章,未經博主允許不得轉載。

一、簡介

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

go-restful項目是一個開源的、基於Golang開發的、用於構建REST風格的Web服務的庫。

REST

REST要求開發者顯式地使用HTTP方法,並與HTTP協議的定義保持一致。REST的基本設計原則是再創建、讀取、更新和刪除(CRUD)操作和HTTP方法之間建立起一對一的映射。根據該映射:

  • GET = 檢索資源的表示
  • POST = 創建,使用某種服務器端的算法將內容發送到服務器以創建指定資源或資源的集合
  • PUT = 創建,如果發送指定URI的完整內容
  • PUT = 更新,如果要更新指定URI的完整內容
  • DELETE = 刪除,如果要請求服務器刪除指定的資源
  • PATCH = 更新,更新某個資源的部分內容
  • OPTIONS = 獲取請求URI相關的通信選項的信息

go-restful庫的特徵

  • 路由請求:支持函數映射到路徑參數(例如{id})
  • 路由可配置
    • (默認)快速路由算法,允許URL路徑上出現靜態元素、正則表達式、動態參數。比如 /meetings/{id} 或者 /static/{subpath:*}
  • 提供了Request API用於從JSON/XML讀取結構和訪問各種參數(路徑參數、查詢參數、頭部參數)
  • 提供了Response API用於將結構(struct)寫入到JSON/XML以及設置頭部
  • 支持使用EntityReaderWriter註冊的自定義編碼
  • 支持在服務級或路由級對請求到響應流的過濾和攔截
  • 支持使用屬性來定義請求範圍的變量
  • 容器Container支持不同HTTP端點上的WebService
  • 請求和響應的有效負載上的內容編碼(gzip,deflate)
  • (使用過濾器)自動響應OPTIONS請求
  • (使用過濾器)自動處理CORS請求
  • 支持Swagger UI編寫的API文檔聲明(閱讀go-restful-openapigo-restful-swagger12
  • 針對HTTP 500狀態碼的恐慌恢復,使用RecoverHandler(…)自定義處理
  • 路由錯誤產生HTTP 404/405/406/415等錯誤,使用ServiceErrorHandler(…)自定義處理
  • 可配置的日誌跟蹤
  • 使用CompressorProvider註冊自定義gzip/deflate的讀入器和輸出器

二、詳解

1、WebServices and Routes

WebService擁有一個Route對象的集合,這些Route對象負責分發即將到來的HTTP請求到相應的函數調用。一般來說,WebService有一個root根路徑(例如:/users),還爲路由定義了常見的MIME類型。WebService必須添加到某個容器以便能從服務器處理HTTP請求。

Route是根據HTTP分發、URL路徑和MIME類型所定義的。

正則表達式匹配路由

路由參數可以使用格式“uri/{var[:regexp]}”或指定版本的“uri/{var:*}”匹配路徑尾部進行指定。例如,/persons/{name:[A-Z][A-Z]} 可用來限制name參數的值只能包含大寫字母。正則表達式必須使用regexp包中的標準Go語法進行描述。https://code.google.com/p/re2/wiki/Syntax,此功能需要使用CurlyRouter。

2、容器(Container)

容器可以hold住一套WebService的集合、過濾器、一個用於http請求多路複用的http.ServeMux。使用語句“restful.Add(…)”和“restful.Filter(…)”,前者可以在容器註冊一個WebService,後者可以過濾。go-restful默認的容器使用http.DefaultServeMux。用戶可以創建自己的容器,以及爲指定的容器創建一個新的http.Server。

container := restful.NewContainer()
server := &http.Server{Addr: ":8081", Handler: container}

3、過濾器(Filter)

過濾器可以動態攔截請求和響應,以及轉換或使用請求和響應中包含的信息。用戶可以使用過濾器來執行常規的日誌記錄、測量、驗證、重定向、設置響應頭部Header等。restful包中有三個針對請求、響應流的鉤子,還可以添加過濾器。每個過濾器必須定義一個FilterFunction:

func(req *restful.Request, resp *restful.Response, chain *restful.FilterChain)

使用如下語句傳遞請求/響應對到下一個過濾器或RouteFunction:

chain.ProcessFilter(req, resp)

4、容器過濾器(Container Filter)

在註冊WebService之前處理:

// 安裝一個(全局的)過濾器到默認的容器
restful.Filter(globalLogging)

5、WebService過濾器(WebService Filter)

在路由WebService之前處理:

// 安裝一個WebService過濾器
ws.Filter(webserviceLogging).Filter(measureTime)

6、路由過濾器(Route Filter)

在調用路由Route相關的函數之前處理:

// 安裝2個鏈式的路由過濾器
ws.Route(ws.GET("/{user-id}").Filter(routeLogging).Filter(NewCountFilter().routeCounter))

例子可見:https://github.com/emicklei/go-restful/blob/master/examples/restful-filters.go

7、響應編碼(Response Encoding)

支持兩種響應編碼:gzip和deflate。要爲所有的響應啓用它們:

restful.DefaultContainer.EnableContentEncoding(true)

如果某個Http請求包含了Accept-Encoding頭部,那麼響應內容必須使用指定的編碼進行壓縮。或者,可以創建一個過濾器執行編碼並安裝它到每一個WebService和Route。

見例子:https://github.com/emicklei/go-restful/blob/master/examples/restful-encoding-filter.go

8、OPTIONS支持

通過安裝預定義的容器過濾器,你的WebService可以響應HTTP OPTIONS請求。

Filter(OPTIONSFilter())

9、CORS

通過安裝CrossOriginResourceSharing過濾器,你的WebService可以處理CORS請求。

cors := CrossOriginResourceSharing{ExposeHeaders: []string{"X-My-Header"}, CookiesAllowed: false, Container: DefaultContainer}
Filter(cors.Filter)

10、異常處理

意想不到的事情發生。如果因爲故障而不能處理請求,服務端需要通過響應告訴客戶端發生了什麼和爲什麼。因此使用HTTP狀態碼,更重要的是要正確的使用狀態碼。

  • 400: Bad Request

如果路徑或查詢參數無效(內容或類型),那麼使用http.StatusBadRequest。

  • 404: Not Found

儘管URI有效,但請求的資源可能不可用。

  • 500: Internal Server Error

如果應用程序邏輯無法處理請求(或編寫響應),則使用http.StatusInternalServerError。

  • 405: Method Not Allowed

請求的URL是有效的,但請求使用的HTTP方法(GET,PUT,POST,…)是不允許的。

  • 406: Not Acceptable

請求的頭部沒有或設置了未知Accept Header。

  • 415: Unsupported Media Type

請求的頭部沒有或設置了未知的Content-Type報頭。

11、ServiceError

除了設置HTTP狀態碼,還應該爲響應選擇寫適當的ServiceError消息。

12、性能選項(Performance Options)

這個包有幾個選項,它們可能會影響服務的性能。重要的是要理解這些選項,正確地設置它們。

  • restful.DefaultContainer.DoNotRecover(false)

DoNotRecover控制是否因返回HTTP 500狀態碼而(恐慌)停止服務。如果設置爲false,那麼容器Container會恢復服務。默認值爲true。

  • restful.SetCompressorProvider(NewBoundedCachedCompressors(20, 20))

如果啓用了內容編碼,那麼獲得新gzip/zlib輸出器(writer)和讀入器(reader)的默認策略是使用sync.Pool。由於輸出器writer是昂貴的結構,當使用預加載緩存時性能提高非常明顯。你也可以注入自己的實現。

13、故障排除(Trouble shooting)

這個包可以對完整的Http請求的匹配過程和過濾器調用產生詳細的日誌記錄。啓用此功能需要你設置restful.StdLogger的實現,例如log.Logger:

restful.TraceLogger(log.New(os.Stdout, "[restful] ", log.LstdFlags|logs.Lshortfile))

使用案例

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章