本文小編為大家詳細(xì)介紹“基于Go語言怎么構(gòu)建RESTful API服務(wù)”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“基于Go語言怎么構(gòu)建RESTful API服務(wù)”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。
在鎮(zhèn)原等地區(qū),都構(gòu)建了全面的區(qū)域性戰(zhàn)略布局,加強(qiáng)發(fā)展的系統(tǒng)性、市場前瞻性、產(chǎn)品創(chuàng)新能力,以專注、極致的服務(wù)理念,為客戶提供成都網(wǎng)站制作、成都網(wǎng)站建設(shè) 網(wǎng)站設(shè)計(jì)制作按需定制制作,公司網(wǎng)站建設(shè),企業(yè)網(wǎng)站建設(shè),品牌網(wǎng)站制作,全網(wǎng)營銷推廣,成都外貿(mào)網(wǎng)站建設(shè),鎮(zhèn)原網(wǎng)站建設(shè)費(fèi)用合理。RESTful API 是一套規(guī)范,它可以規(guī)范我們?nèi)绾螌Ψ?wù)器上的資源進(jìn)行操作。在了解 RESTful API 之前,我先為你介紹下 HTTP Method,因?yàn)?RESTful API 和它是密不可分的。
說起 HTTP Method,最常見的就是POST和GET,其實(shí)最早在 HTTP 0.9 版本中,只有一個(gè)GET方法,該方法是一個(gè)冪等方法,用于獲取服務(wù)器上的資源,也就是我們在瀏覽器中直接輸入網(wǎng)址回車請求的方法。
在 HTTP 1.0 版本中又增加了HEAD和POST方法,其中常用的是 POST 方法,一般用于給服務(wù)端提交一個(gè)資源,導(dǎo)致服務(wù)器的資源發(fā)生變化。
隨著網(wǎng)絡(luò)越來越復(fù)雜,發(fā)現(xiàn)這兩個(gè)方法是不夠用的,就繼續(xù)新增了方法。所以在 HTTP1.1 版本的時(shí)候,一口氣增加到了 9 個(gè),新增的方法有 HEAD、OPTIONS、PUT、DELETE、TRACE、PATCH 和 CONNECT。下面我為你一一介紹它們的作用。
GET 方法可請求一個(gè)指定資源的表示形式,使用 GET 的請求應(yīng)該只被用于獲取數(shù)據(jù)。
HEAD 方法用于請求一個(gè)與 GET 請求的響應(yīng)相同的響應(yīng),但沒有響應(yīng)體。
POST 方法用于將實(shí)體提交到指定的資源,通常導(dǎo)致服務(wù)器上的狀態(tài)變化或副作用。
PUT 方法用于請求有效載荷替換目標(biāo)資源的所有當(dāng)前表示。
DELETE 方法用于刪除指定的資源。
CONNECT 方法用于建立一個(gè)到由目標(biāo)資源標(biāo)識的服務(wù)器的隧道。
OPTIONS 方法用于描述目標(biāo)資源的通信選項(xiàng)。
TRACE 方法用于沿著到目標(biāo)資源的路徑執(zhí)行一個(gè)消息環(huán)回測試。
PATCH 方法用于對資源應(yīng)用部分修改。
從以上每個(gè)方法的介紹可以看到,HTTP 規(guī)范針對每個(gè)方法都給出了明確的定義,所以我們使用的時(shí)候也要盡可能地遵循這些定義,這樣我們在開發(fā)中才可以更好地協(xié)作。
理解了這些 HTTP 方法,就可以更好地理解 RESTful API 規(guī)范了,因?yàn)?RESTful API 規(guī)范就是基于這些 HTTP 方法規(guī)范我們對服務(wù)器資源的操作,同時(shí)規(guī)范了 URL 的樣式和 HTTP Status Code。
在 RESTful API 中,使用的主要是以下五種 HTTP 方法:
GET,表示讀取服務(wù)器上的資源;
POST,表示在服務(wù)器上創(chuàng)建資源;
PUT,表示更新或者替換服務(wù)器上的資源;
DELETE,表示刪除服務(wù)器上的資源;
PATCH,表示更新 / 修改資源的一部分。
以上 HTTP 方法在 RESTful API 規(guī)范中是一個(gè)操作,操作的就是服務(wù)器的資源,服務(wù)器的資源通過特定的 URL 表示。
現(xiàn)在我們通過一些示例讓你更好地理解 RESTful API,如下所示:
HTTP GET http://localhost:1000/users HTTP GET http://localhost:1000/user/123
以上是兩個(gè) GET 方法的示例:
第一個(gè)表示獲取所有用戶的信息
第二個(gè)表示獲取 ID 為 123 用戶的信息
下面再看一個(gè) POST 方法的示例,如下所示:
HTTP POST http://localhost:1000/user
這個(gè)示例表示創(chuàng)建一個(gè)用戶,通過 POST 方法給服務(wù)器提供創(chuàng)建這個(gè)用戶所需的全部信息。
現(xiàn)在你已經(jīng)知道了如何創(chuàng)建一個(gè)用戶,那么如果要更新某個(gè)特定的用戶怎么做呢?其實(shí)也非常簡單,示例代碼如下所示:
HTTP PUT http://localhost:1000/user/123
這表示要更新 / 替換 ID 為 123 的這個(gè)用戶,在更新的時(shí)候,會通過 PUT 方法提供更新這個(gè)用戶需要的全部用戶信息。這里 PUT 方法和 POST 方法不太一樣的是,從 URL 上看,PUT 方法操作的是單個(gè)資源,比如這里 ID 為 123 的用戶。
看到這里,相信你已經(jīng)知道了如何刪除一個(gè)用戶,示例代碼如下所示:
HTTP DELETE http://localhost:1000/user/123
DELETE 方法的使用和 PUT 方法一樣,也是操作單個(gè)資源,這里是刪除 ID 為 123 的這個(gè)用戶。
相信你已經(jīng)非常了解什么是 RESTful API 了,現(xiàn)在開始,我會帶你通過一個(gè)使用 Golang 實(shí)現(xiàn) RESTful API 風(fēng)格的示例,加深 RESTful API 的理解。
Go 語言的一個(gè)很大的優(yōu)勢,就是可以很容易地開發(fā)出網(wǎng)絡(luò)后臺服務(wù),而且性能快、效率高。在開發(fā)后端 HTTP 網(wǎng)絡(luò)應(yīng)用服務(wù)的時(shí)候,我們需要處理很多 HTTP 的請求訪問,比如常見的RESTful API 服務(wù),就要處理很多 HTTP 請求,然后把處理的信息返回給使用者。對于這類需求,Golang 提供了內(nèi)置的 net/http 包幫我們處理這些 HTTP 請求,讓我們可以比較方便地開發(fā)一個(gè) HTTP 服務(wù)。
下面我們來看一個(gè)簡單的 HTTP 服務(wù)的 Go 語言實(shí)現(xiàn),代碼如下所示:
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:王五") }
這個(gè)示例運(yùn)行后,你在瀏覽器中輸入http://localhost:1000/users, 就可以看到如下內(nèi)容信息:
ID:1,Name:張三
ID:2,Name:李四
ID:3,Name:王五
也就是獲取所有的用戶信息,但是這并不是一個(gè) RESTful API,因?yàn)槭褂谜卟粌H可以通過 HTTP GET 方法獲得所有的用戶信息,還可以通過 POST、DELETE、PUT 等 HTTP 方法獲得所有的用戶信息,這顯然不符合 RESTful API 的規(guī)范。
現(xiàn)在我對以上示例進(jìn)行修改,使它符合 RESTful API 的規(guī)范,修改后的示例代碼如下所示:
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 函數(shù),在該函數(shù)中增加了只在使用 GET 方法時(shí),才獲得所有用戶的信息,其他情況返回 not found。
現(xiàn)在再運(yùn)行這個(gè)示例,會發(fā)現(xiàn)只能通過 HTTP GET 方法進(jìn)行訪問了,使用其他方法會提示 not found。
在項(xiàng)目中最常見的是使用 JSON 格式傳輸信息,也就是我們提供的 RESTful API 要返回 JSON 內(nèi)容給使用者。
同樣用上面的示例,我把它改造成可以返回 JSON 內(nèi)容的方式,示例代碼如下所示:
//數(shù)據(jù)源,類似MySQL中的數(shù)據(jù) 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 }
從以上代碼可以看到,這次的改造主要是新建了一個(gè) User 結(jié)構(gòu)體,并且使用 users 這個(gè)切片存儲所有的用戶,然后在 handleUsers 函數(shù)中把它轉(zhuǎn)化為一個(gè) JSON 數(shù)組返回。這樣,就實(shí)現(xiàn)了基于 JSON 數(shù)據(jù)格式的 RESTful API。
運(yùn)行這個(gè)示例,在瀏覽器中輸入http://localhost:1000/users,可以看到如下信息:
[{"ID":1,"Name":"張三"},{"ID":2,"Name":"李四"},{"ID":3,"Name":"王五"}]
這已經(jīng)是 JSON 格式的用戶信息,包含了所有用戶。
雖然 Go 語言自帶的 net/http 包,可以比較容易地創(chuàng)建 HTTP 服務(wù),但是它也有很多不足:
不能單獨(dú)地對請求方法(POST、GET 等)注冊特定的處理函數(shù)
不支持 Path 變量參數(shù)
不能自動對 Path 進(jìn)行校準(zhǔn)
性能一般
基于以上這些不足,出現(xiàn)了很多 Golang Web 框架,如 Mux,Gin、Fiber 等,今天我要為你介紹的就是這款使用最多的 Gin 框架。
Gin 框架是一個(gè)在 Github 上開源的 Web 框架,封裝了很多 Web 開發(fā)需要的通用功能,并且性能也非常高,可以讓我們很容易地寫出 RESTful API。
Gin 框架其實(shí)是一個(gè)模塊,也就是 Go Mod,所以采用 Go Mod 的方法引入即可。首先需要下載安裝 Gin 框架,安裝代碼如下:
go get -u github.com/gin-gonic/gin
然后就可以在 Go 語言代碼中導(dǎo)入使用了,導(dǎo)入代碼如下:
import "github.com/gin-gonic/gin"
通過以上安裝和導(dǎo)入這兩個(gè)步驟,就可以在你的 Go 語言項(xiàng)目中使用 Gin 框架了。
現(xiàn)在,已經(jīng)引入了 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 方法就可以創(chuàng)建一個(gè)只處理 HTTP GET 方法的服務(wù),而且輸出 JSON 格式的數(shù)據(jù)也非常簡單,使用 c.JSON 方法即可。
最后通過 Run 方法啟動 HTTP 服務(wù),監(jiān)聽在 1000 端口?,F(xiàn)在運(yùn)行這個(gè) Gin 示例,在瀏覽器中輸入http://localhost:1000/users,看到的信息和通過 net/http 包實(shí)現(xiàn)的效果是一樣的。
現(xiàn)在你已經(jīng)可以使用 Gin 獲取所有用戶,還可以獲取特定的用戶,那么你也應(yīng)該知道如何新增一個(gè)用戶了,現(xiàn)在我通過 Gin 實(shí)現(xiàn)如何新增一個(gè)用戶,看和你想的方案是否相似。
根據(jù) RESTful API 規(guī)范,實(shí)現(xiàn)新增使用的是 POST 方法,并且 URL 的格式為http://localhost:1000/users,向這個(gè) URL 發(fā)送數(shù)據(jù),就可以新增一個(gè)用戶,然后返回創(chuàng)建的用戶信息。
現(xiàn)在我使用 Gin 框架實(shí)現(xiàn)新增一個(gè)用戶,示例代碼如下:
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 值,然后生成一個(gè) User 用戶,最后把它存儲到 users 集合中,達(dá)到新增用戶的目的。
在這個(gè)示例中,使用 POST 方法來新增用戶,所以只能通過 POST 方法才能新增用戶成功。
現(xiàn)在運(yùn)行這個(gè)示例,然后通過如下命令發(fā)送一個(gè)新增用戶的請求,查看結(jié)果:
? curl -X POST -d "name=Ele" http://localhost:1000/users
{"ID":4,"Name":"Ele"}
可以看到新增用戶成功,并且返回了新增的用戶,還有分配的 ID。
現(xiàn)在你已經(jīng)掌握了如何使用 Gin 框架創(chuàng)建一個(gè)簡單的 RESTful API,并且可以返回所有的用戶信息,那么如何獲取特定用戶的信息呢?
下面我通過 Gin 框架 Path 路徑參數(shù)來實(shí)現(xiàn)獲得特定用戶的信息功能,示例代碼如下:
func main() { //省略沒有改動的代碼 r.GET("/users/:id", getUser) } func getUser(c *gin.Context) { id := c.Param("id") var user User found := false //類似于數(shù)據(jù)庫的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 路徑參數(shù),比如示例中的 :id,然后在 getUser 函數(shù)中可以通過 c.Param("id") 獲取需要查詢用戶的 ID 值。PS:Param 方法的參數(shù)要和 Path 路徑參數(shù)中的一致,比如示例中都是 ID。
現(xiàn)在運(yùn)行這個(gè)示例,通過瀏覽器訪問http://localhost:1000/users/4,就可以獲得 ID 為 4 的用戶,輸出信息如下所示:
{"ID":4,"Name":"Ele"}
可以看到,已經(jīng)正確的獲取到了 ID 為 4 的用戶,他的名字叫Ele。
假如我們訪問一個(gè)不存在的 ID,會得到什么結(jié)果呢?比如 99,示例如下所示:
curl http://localhost:1000/users/99
{"message":"用戶不存在"}
從以上示例輸出可以看到,返回了『用戶不存在』的信息,和我們代碼中處理的邏輯一樣。
讀到這里,這篇“基于Go語言怎么構(gòu)建RESTful API服務(wù)”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點(diǎn)還需要大家自己動手實(shí)踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。