在RESTful API 設計規範中,有一部分是針對HTTP 方法動作的定義,規定了這些方法對於具體資源的操作方式,比如GET、POST這兩個是我們常用的,除了他們,HTTP還定義了很多HTTP 方法。HTTP Method
最開始的HTTP 0.9版本只有一個GET方法,也就是我們在瀏覽器中直接輸入網址回車請求的方法,這是一個冪等方法,用於獲取伺服器上的資源。
在HTTP 1.0的時候又增加了HEAD和POST方法,其中常用的就是POST方法,一般用於我們給服務端提交一個資源,導致伺服器的資源發生變化。
在HTTP1.1版本,也就是HTTP 1系列的最後一個版本中,也是我們當下比較常用的HTTP版本,增加了更多的HTTP 方法。比如OPTIONS, PUT, DELETE, TRACE和CONNECT,這樣在HTTP 1.1 版本中,HTTP的方法達到了8個。
下面我們看下這些方法被賦予的意義。
GET
GET方法請求一個指定資源的表示形式. 使用GET的請求應該只被用於獲取資料.
HEAD
HEAD方法請求一個與GET請求的響應相同的響應,但沒有響應體.
POST
POST方法用於將實體提交到指定的資源,通常導致在伺服器上的狀態變化或副作用.
PUT
PUT方法用請求有效載荷替換目標資源的所有當前表示。
DELETE
CONNECT
CONNECT方法建立一個到由目標資源標識的伺服器的隧道。
OPTIONS
OPTIONS方法用於描述目標資源的通訊選項。
TRACE
TRACE方法沿著到目標資源的路徑執行一個訊息環回測試。
PATCH
PATCH方法用於對資源應用部分修改。
以上摘自https://developer.mozilla.org/ 對於HTTP 請求方法的介紹。
透過以上的介紹,我們可以看到,其實HTTP的規範,對這些方法的用途都有了明確的定義,而我們使用的過程中,也儘可能的遵循這些定義,這樣我們在開發中才可以更好的協作。對於以上請求方法,目前的大部分瀏覽器都支援。
RESTful API 規範其實我們應該可以發現,我們開發的一個個Web應用服務或者程式,其實就是對伺服器的資源的CRUD(建立、檢索、更新和刪除),所以 RESTful API 的規範建議我們使用特定的HTTP方法來對伺服器上的資源進行操作。
在 RESTful API 中,使用的主要是以下五種HTTP方法:
GET,表示讀取伺服器上的資源POST,表示在伺服器上建立資源PUT,表示更新或者替換伺服器上的資源DELETE,表示刪除伺服器上的資源PATCH,表示更新/修改資源的一部分這裡我透過一些URL示例來更好的說明這些HTTP方法的使用。
HTTP GET https://www.flysnow.org/usersHTTP GET https://www.flysnow.org/users/123
以上是兩個GET方法的示例,第一個表示獲取所有使用者的資訊;第二個表示獲取id為123使用者的資訊。
HTTP POST https://www.flysnow.org/users
這表示建立一個使用者,會透過POST給伺服器提供建立這個使用者所需的全部資訊。注意這裡users是個複數
HTTP PUT https://www.flysnow.org/users/123
這表示要更新/替換id為123的這個使用者,在更新的時候,會透過PUT提供更新這個使用者需要的全部使用者資訊。這裡PUT和POST不太一樣的是,從URL上看,PUT操作的是單個資源,比如這裡id為123的這個使用者。
HTTP PATCH https://www.flysnow.org/users/123
PATCH也更新資源,它和PUT不一樣的是,它只能更新這個資源的部分資訊,而不是全部(這種也叫替換),是部分更新。所以我們無需提供全部使用者資訊給伺服器,需要更新哪些就提供哪些。
RESTful API 規範關於這部分HTTP方法的定義是非常好的,這讓我們可以在編寫API的時候更加規範,可讀性強,便於協作。RESTful API規範這麼好,對於我們強大的Golang Gin這個框架來說,自然不會忘記,Golang Gin為我們提供了一套非常簡潔的介面,讓我們可以很容易的實現RESTful API的規範。
Gin RESTful API 實現。現在我們透過一個具體的Go程式碼示例,來演示如上我們所說的RESTful API定義的資源操作,但是這裡的實現我們以演示Gin便捷的HTTP Method方法註冊為主,會忽略很多具體業務邏輯的程式碼,並且不會嚴格的按照RESTful API的 Status Code 進行返回。
1234
type User struct { ID uint64 Name string}
首先我們定義一個使用者User,用來表示我們需要操作的使用者。
func main() { users := []User{{ID: 123, Name: "張三"}, {ID: 456, Name: "李四"}} r := gin.Default() r.GET("/users", func(c *gin.Context) { c.JSON(200, users) }) r.Run(":8080")}
這裡我們透過GET方法就可以很容易的註冊一HTTP GET請求的處理邏輯,這裡是返回所有的使用者資訊,JSON的格式。
我們執行這段程式碼,在瀏覽器裡開啟http://localhost:8080/users,就可以看到如下資訊:
[{"ID":123,"Name":"張三"},{"ID":456,"Name":"李四"}]
Gin不光為我們提供了快捷的GET方法,還有其他方法,可以很容易的讓我們實現對應的HTTP Method方法註冊。
r.POST("/users", func(context *gin.Context) { //建立一個使用者 }) r.DELETE("/usrs/123", func(context *gin.Context) { //刪除ID為123的使用者 }) r.PUT("/usrs/123", func(context *gin.Context) { //更新ID為123的使用者 }) r.PATCH("/usrs/123", func(context *gin.Context) { //更新ID為123使用者的部分資訊 })
此外還有不常用的HEAD、OPTIONS、TRACE、CONNECT等方法,從中可以看出,Gin的API非常友好,可以讓我們很容易的使用相應的方法來註冊我們對某個HTTP Method的處理。
有的朋友們可能會想,我這麼一個個註冊太麻煩了,比如想一次註冊所有的HTTP Method的方法,有沒有便捷的方式。別說,這個還真有。
// Any registers a route that matches all the HTTP methods.// GET, POST, PUT, PATCH, HEAD, OPTIONS, DELETE, CONNECT, TRACE.func (group *RouterGroup) Any(relativePath string, handlers ...HandlerFunc) IRoutes { group.handle("GET", relativePath, handlers) group.handle("POST", relativePath, handlers) group.handle("PUT", relativePath, handlers) group.handle("PATCH", relativePath, handlers) group.handle("HEAD", relativePath, handlers) group.handle("OPTIONS", relativePath, handlers) group.handle("DELETE", relativePath, handlers) group.handle("CONNECT", relativePath, handlers) group.handle("TRACE", relativePath, handlers) return group.returnObj()}
Gin提供了Any方法,可以一次性註冊以上這些HTTP Method方法。如果你只想註冊其中某兩個、或者三個方法,Gin就沒有這樣的便捷方法了,不過Gin為我們提供了通用的Handle方法,我們可以包裝一下使用。
func Handle(r *gin.Engine, httpMethods []string, relativePath string, handlers ...gin.HandlerFunc) gin.IRoutes { var routes gin.IRoutes for _, httpMethod := range httpMethods { routes = r.Handle(httpMethod, relativePath, handlers...) } return routes}
有了這個函式,我們就可以類似如下這樣使用:
Handle(r, []string{"GET", "POST"}, "/", func(c *gin.Context) { //同時註冊GET、POST請求方法 })
雖然這種方式比較便利,但是並不太推薦,因為他破壞了Resultful 規範中HTTP Method的約束。
小結到這裡這篇也就要結束了,在這篇中,雖然我們是在講Gin的這些便捷的方法註冊,但是我們也介紹了HTTP Method,Restful API規範,這樣相信大家知道來龍去脈,可以對這些方法的使用更容易理解。
相信大家也看到了,如果對於這些請求的URL我們一個個去註冊,比如張三使用者和李四使用者,分別註冊一個對應的GET方法,是很繁瑣的,所以Gin為我們提供了URL路由的模糊匹配,比如URL路徑中的引數,下一篇我們再講。