您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“基于Go語言怎么構建RESTful API服務”,內容詳細,步驟清晰,細節處理妥當,希望這篇“基于Go語言怎么構建RESTful API服務”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學習新知識吧。
RESTful API 是一套規范,它可以規范我們如何對服務器上的資源進行操作。在了解 RESTful API 之前,我先為你介紹下 HTTP Method,因為 RESTful API 和它是密不可分的。
說起 HTTP Method,最常見的就是POST和GET,其實最早在 HTTP 0.9 版本中,只有一個GET方法,該方法是一個冪等方法,用于獲取服務器上的資源,也就是我們在瀏覽器中直接輸入網址回車請求的方法。
在 HTTP 1.0 版本中又增加了HEAD和POST方法,其中常用的是 POST 方法,一般用于給服務端提交一個資源,導致服務器的資源發生變化。
隨著網絡越來越復雜,發現這兩個方法是不夠用的,就繼續新增了方法。所以在 HTTP1.1 版本的時候,一口氣增加到了 9 個,新增的方法有 HEAD、OPTIONS、PUT、DELETE、TRACE、PATCH 和 CONNECT。下面我為你一一介紹它們的作用。
GET 方法可請求一個指定資源的表示形式,使用 GET 的請求應該只被用于獲取數據。
HEAD 方法用于請求一個與 GET 請求的響應相同的響應,但沒有響應體。
POST 方法用于將實體提交到指定的資源,通常導致服務器上的狀態變化或副作用。
PUT 方法用于請求有效載荷替換目標資源的所有當前表示。
DELETE 方法用于刪除指定的資源。
CONNECT 方法用于建立一個到由目標資源標識的服務器的隧道。
OPTIONS 方法用于描述目標資源的通信選項。
TRACE 方法用于沿著到目標資源的路徑執行一個消息環回測試。
PATCH 方法用于對資源應用部分修改。
從以上每個方法的介紹可以看到,HTTP 規范針對每個方法都給出了明確的定義,所以我們使用的時候也要盡可能地遵循這些定義,這樣我們在開發中才可以更好地協作。
理解了這些 HTTP 方法,就可以更好地理解 RESTful API 規范了,因為 RESTful API 規范就是基于這些 HTTP 方法規范我們對服務器資源的操作,同時規范了 URL 的樣式和 HTTP Status Code。
在 RESTful API 中,使用的主要是以下五種 HTTP 方法:
GET,表示讀取服務器上的資源;
POST,表示在服務器上創建資源;
PUT,表示更新或者替換服務器上的資源;
DELETE,表示刪除服務器上的資源;
PATCH,表示更新 / 修改資源的一部分。
以上 HTTP 方法在 RESTful API 規范中是一個操作,操作的就是服務器的資源,服務器的資源通過特定的 URL 表示。
現在我們通過一些示例讓你更好地理解 RESTful API,如下所示:
HTTP GET http://localhost:1000/users HTTP GET http://localhost:1000/user/123
以上是兩個 GET 方法的示例:
第一個表示獲取所有用戶的信息
第二個表示獲取 ID 為 123 用戶的信息
下面再看一個 POST 方法的示例,如下所示:
HTTP POST http://localhost:1000/user
這個示例表示創建一個用戶,通過 POST 方法給服務器提供創建這個用戶所需的全部信息。
現在你已經知道了如何創建一個用戶,那么如果要更新某個特定的用戶怎么做呢?其實也非常簡單,示例代碼如下所示:
HTTP PUT http://localhost:1000/user/123
這表示要更新 / 替換 ID 為 123 的這個用戶,在更新的時候,會通過 PUT 方法提供更新這個用戶需要的全部用戶信息。這里 PUT 方法和 POST 方法不太一樣的是,從 URL 上看,PUT 方法操作的是單個資源,比如這里 ID 為 123 的用戶。
看到這里,相信你已經知道了如何刪除一個用戶,示例代碼如下所示:
HTTP DELETE http://localhost:1000/user/123
DELETE 方法的使用和 PUT 方法一樣,也是操作單個資源,這里是刪除 ID 為 123 的這個用戶。
相信你已經非常了解什么是 RESTful API 了,現在開始,我會帶你通過一個使用 Golang 實現 RESTful API 風格的示例,加深 RESTful API 的理解。
Go 語言的一個很大的優勢,就是可以很容易地開發出網絡后臺服務,而且性能快、效率高。在開發后端 HTTP 網絡應用服務的時候,我們需要處理很多 HTTP 的請求訪問,比如常見的RESTful API 服務,就要處理很多 HTTP 請求,然后把處理的信息返回給使用者。對于這類需求,Golang 提供了內置的 net/http 包幫我們處理這些 HTTP 請求,讓我們可以比較方便地開發一個 HTTP 服務。
下面我們來看一個簡單的 HTTP 服務的 Go 語言實現,代碼如下所示:
func main() { http.HandleFunc("/users",handleUsers) http.ListenAndServe(":1000", nil) } func handleUsers(w http.ResponseWriter, r *http.Request){ fmt.Fprintln(w,"ID:1,Name:張三") fmt.Fprintln(w,"ID:2,Name:李四") fmt.Fprintln(w,"ID:3,Name:王五") }
這個示例運行后,你在瀏覽器中輸入http://localhost:1000/users, 就可以看到如下內容信息:
ID:1,Name:張三
ID:2,Name:李四
ID:3,Name:王五
也就是獲取所有的用戶信息,但是這并不是一個 RESTful API,因為使用者不僅可以通過 HTTP GET 方法獲得所有的用戶信息,還可以通過 POST、DELETE、PUT 等 HTTP 方法獲得所有的用戶信息,這顯然不符合 RESTful API 的規范。
現在我對以上示例進行修改,使它符合 RESTful API 的規范,修改后的示例代碼如下所示:
func handleUsers(w http.ResponseWriter, r *http.Request){ switch r.Method { case "GET": w.WriteHeader(http.StatusOK) fmt.Fprintln(w,"ID:1,Name:張三") fmt.Fprintln(w,"ID:2,Name:李四") fmt.Fprintln(w,"ID:3,Name:王五") default: w.WriteHeader(http.StatusNotFound) fmt.Fprintln(w,"not found") } }
這里我只修改了 handleUsers 函數,在該函數中增加了只在使用 GET 方法時,才獲得所有用戶的信息,其他情況返回 not found。
現在再運行這個示例,會發現只能通過 HTTP GET 方法進行訪問了,使用其他方法會提示 not found。
在項目中最常見的是使用 JSON 格式傳輸信息,也就是我們提供的 RESTful API 要返回 JSON 內容給使用者。
同樣用上面的示例,我把它改造成可以返回 JSON 內容的方式,示例代碼如下所示:
//數據源,類似MySQL中的數據 var users = []User{ {ID: 1,Name: "張三"}, {ID: 2,Name: "李四"}, {ID: 3,Name: "王五"}, } func handleUsers(w http.ResponseWriter, r *http.Request){ switch r.Method { case "GET": users,err:=json.Marshal(users) if err!=nil { w.WriteHeader(http.StatusInternalServerError) fmt.Fprint(w,"{"message": ""+err.Error()+""}") }else { w.WriteHeader(http.StatusOK) w.Write(users) } default: w.WriteHeader(http.StatusNotFound) fmt.Fprint(w,"{"message": "not found"}") } } //用戶 type User struct { ID int Name string }
從以上代碼可以看到,這次的改造主要是新建了一個 User 結構體,并且使用 users 這個切片存儲所有的用戶,然后在 handleUsers 函數中把它轉化為一個 JSON 數組返回。這樣,就實現了基于 JSON 數據格式的 RESTful API。
運行這個示例,在瀏覽器中輸入http://localhost:1000/users,可以看到如下信息:
[{"ID":1,"Name":"張三"},{"ID":2,"Name":"李四"},{"ID":3,"Name":"王五"}]
這已經是 JSON 格式的用戶信息,包含了所有用戶。
雖然 Go 語言自帶的 net/http 包,可以比較容易地創建 HTTP 服務,但是它也有很多不足:
不能單獨地對請求方法(POST、GET 等)注冊特定的處理函數
不支持 Path 變量參數
不能自動對 Path 進行校準
性能一般
基于以上這些不足,出現了很多 Golang Web 框架,如 Mux,Gin、Fiber 等,今天我要為你介紹的就是這款使用最多的 Gin 框架。
Gin 框架是一個在 Github 上開源的 Web 框架,封裝了很多 Web 開發需要的通用功能,并且性能也非常高,可以讓我們很容易地寫出 RESTful API。
Gin 框架其實是一個模塊,也就是 Go Mod,所以采用 Go Mod 的方法引入即可。首先需要下載安裝 Gin 框架,安裝代碼如下:
go get -u github.com/gin-gonic/gin
然后就可以在 Go 語言代碼中導入使用了,導入代碼如下:
import "github.com/gin-gonic/gin"
通過以上安裝和導入這兩個步驟,就可以在你的 Go 語言項目中使用 Gin 框架了。
現在,已經引入了 Gin 框架,下面我就是用 Gin 框架重寫上面的示例,修改的代碼如下所示:
func main() { r:=gin.Default() r.GET("/users", listUser) r.Run(":1000") } func listUser(c *gin.Context) { c.JSON(200,users) }
相比 net/http 包,Gin 框架的代碼非常簡單,通過它的 GET 方法就可以創建一個只處理 HTTP GET 方法的服務,而且輸出 JSON 格式的數據也非常簡單,使用 c.JSON 方法即可。
最后通過 Run 方法啟動 HTTP 服務,監聽在 1000 端口。現在運行這個 Gin 示例,在瀏覽器中輸入http://localhost:1000/users,看到的信息和通過 net/http 包實現的效果是一樣的。
現在你已經可以使用 Gin 獲取所有用戶,還可以獲取特定的用戶,那么你也應該知道如何新增一個用戶了,現在我通過 Gin 實現如何新增一個用戶,看和你想的方案是否相似。
根據 RESTful API 規范,實現新增使用的是 POST 方法,并且 URL 的格式為http://localhost:1000/users,向這個 URL 發送數據,就可以新增一個用戶,然后返回創建的用戶信息。
現在我使用 Gin 框架實現新增一個用戶,示例代碼如下:
func main() { //省略沒有改動的代碼 r.POST("/users", createUser) } func createUser(c *gin.Context) { name := c.DefaultPostForm("name", "") if name != "" { u := User{ID: len(users) + 1, Name: name} users = append(users, u) c.JSON(http.StatusCreated,u) } else { c.JSON(http.StatusOK, gin.H{ "message": "請輸入用戶名稱", }) } }
以上新增用戶的主要邏輯是獲取客戶端上傳的 name 值,然后生成一個 User 用戶,最后把它存儲到 users 集合中,達到新增用戶的目的。
在這個示例中,使用 POST 方法來新增用戶,所以只能通過 POST 方法才能新增用戶成功。
現在運行這個示例,然后通過如下命令發送一個新增用戶的請求,查看結果:
? curl -X POST -d "name=Ele" http://localhost:1000/users
{"ID":4,"Name":"Ele"}
可以看到新增用戶成功,并且返回了新增的用戶,還有分配的 ID。
現在你已經掌握了如何使用 Gin 框架創建一個簡單的 RESTful API,并且可以返回所有的用戶信息,那么如何獲取特定用戶的信息呢?
下面我通過 Gin 框架 Path 路徑參數來實現獲得特定用戶的信息功能,示例代碼如下:
func main() { //省略沒有改動的代碼 r.GET("/users/:id", getUser) } func getUser(c *gin.Context) { id := c.Param("id") var user User found := false //類似于數據庫的SQL查詢 for _, u := range users { if strings.EqualFold(id, strconv.Itoa(u.ID)) { user = u found = true break } } if found { c.JSON(200, user) } else { c.JSON(404, gin.H{ "message": "用戶不存在", }) } }
在 Gin 框架中,路徑中使用冒號表示 Path 路徑參數,比如示例中的 :id,然后在 getUser 函數中可以通過 c.Param("id") 獲取需要查詢用戶的 ID 值。PS:Param 方法的參數要和 Path 路徑參數中的一致,比如示例中都是 ID。
現在運行這個示例,通過瀏覽器訪問http://localhost:1000/users/4,就可以獲得 ID 為 4 的用戶,輸出信息如下所示:
{"ID":4,"Name":"Ele"}
可以看到,已經正確的獲取到了 ID 為 4 的用戶,他的名字叫Ele。
假如我們訪問一個不存在的 ID,會得到什么結果呢?比如 99,示例如下所示:
curl http://localhost:1000/users/99
{"message":"用戶不存在"}
從以上示例輸出可以看到,返回了『用戶不存在』的信息,和我們代碼中處理的邏輯一樣。
讀到這里,這篇“基于Go語言怎么構建RESTful API服務”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。