Golang使用Gin創(chuàng)建Restful API的實(shí)現(xiàn)
今天學(xué)習(xí)下Go語(yǔ)言如何集成Gin框架編寫Restful Web API的基本操作。Gin框架簡(jiǎn)化了Go原生語(yǔ)言構(gòu)建Web應(yīng)用程序的復(fù)雜度,在今天的學(xué)習(xí)中,將學(xué)會(huì)使用Gin構(gòu)建路由請(qǐng)求、數(shù)據(jù)檢索、JSON響應(yīng)封裝等最簡(jiǎn)單的Web服務(wù)。
基本要求
- Go 1.16 及更高版本
- 合適的編譯工具 - text編輯器也滿足要求
- 命令終端 - Linux、Mac系統(tǒng)shell, Windows系統(tǒng)的Cmd、PowerShell
- curl 工具 - curl 是一個(gè)利用URL語(yǔ)法在命令行下工作的文件傳輸工具
設(shè)計(jì)API
遵循Restful API 架構(gòu)風(fēng)格,構(gòu)建以下兩個(gè)Http Api:
- /albums
- GET - 獲取數(shù)據(jù)列表,以JSON格式返回
- POST - 接收客戶端發(fā)送的JSON請(qǐng)求,新增數(shù)據(jù)項(xiàng)
- /albums/:id
- GET - 根據(jù)指定ID獲取特定的數(shù)據(jù),跟SpringBoot框架動(dòng)態(tài)ID使用 {id} 不同,Gin框架在語(yǔ)法上使用 冒號(hào): 表明該參數(shù)為為前端傳遞的動(dòng)態(tài)參數(shù)
代碼開發(fā)
創(chuàng)建項(xiàng)目
創(chuàng)建項(xiàng)目目錄
$ mkdir web-service-gin $ cd web-service-gin
項(xiàng)目初始化 - 使用go mod init 命令初始化
$ go mod init example/web-service-gin
該命令會(huì)自動(dòng)創(chuàng)建go.mod文件,該文件用于管理Go應(yīng)用中的依賴,作用類似于Java語(yǔ)言中的Maven
創(chuàng)建數(shù)據(jù)格式
為了簡(jiǎn)化Demo開發(fā)難度,將直接使用內(nèi)存中的數(shù)據(jù),不跟DB進(jìn)行交互(真實(shí)項(xiàng)目中不推薦)。首先在項(xiàng)目根目錄下創(chuàng)建main.go文件,文件內(nèi)容如下:
package main// 定義JSON 返回格式type album struct { ID string `json:"id"` Title string `json:"title"` Artist string `json:"artist"` Price float64 `json:"price"`}// 內(nèi)存中存儲(chǔ)的數(shù)組var albums = []album{ {ID: "1", Title: "Blue Train", Artist: "John Coltrane", Price: 56.99}, {ID: "2", Title: "Jeru", Artist: "Gerry Mulligan", Price: 17.99}, {ID: "3", Title: "Sarah Vaughan and Clifford Brown", Artist: "Sarah Vaughan", Price: 39.99},}
Restful API
返回?cái)?shù)據(jù)列表
當(dāng)客戶端使用Get方式請(qǐng)求**/albums**路徑時(shí),需要按照J(rèn)SON格式返回所有數(shù)據(jù)(這里先不討論分頁(yè))。實(shí)現(xiàn)該需求,代碼開發(fā)時(shí),需要注意以下兩點(diǎn)
- 準(zhǔn)備響應(yīng)邏輯
- 將請(qǐng)求路徑跟響應(yīng)邏輯進(jìn)行匹配
處理函數(shù)
// 在main.go新增函數(shù) // getAlbums responds with the list of all albums as JSON. func getAlbums(c *gin.Context) { c.IndentedJSON(http.StatusOK, albums) }
代碼說明:
編寫getAlbums函數(shù),該函數(shù)接受gin.Context參數(shù)。您可以為該函數(shù)指定任何你喜歡的函數(shù)名稱。gin.Context是Gin框架中最重要的部分,它攜帶HTTP Request請(qǐng)求的所有細(xì)節(jié),如請(qǐng)求參數(shù)、驗(yàn)證、JSON序列化等
調(diào)用Context.IndedJSON將結(jié)構(gòu)序列化為JSON并將其添加到響應(yīng)中。Context.IndedJSON函數(shù)的第一個(gè)參數(shù)是要發(fā)送給客戶端的HTTP狀態(tài)代碼。在這里默認(rèn)為200,表示請(qǐng)求成功
**路由處理 **
// 在 main.go 文件中新增 func main() { router := gin.Default() router.GET("/albums", getAlbums) router.Run("localhost:8080") }
代碼說明
- 使用默認(rèn)方式初始化Gin Router路由
- 使用GET方法關(guān)聯(lián)**/albums** 和 getAlbums 函數(shù)
- 調(diào)用Run函數(shù)啟動(dòng)服務(wù)器
新增依賴
// 在 main.go 文件中新增 package main import ( "net/http" "github.com/gin-gonic/gin" )
運(yùn)行服務(wù)
添加依賴 - 使用以下命令 拉取Gin框架依賴包
$ go get .
運(yùn)行服務(wù)
$ go run .
使用curl工具發(fā)送Http請(qǐng)求 - 打開另外的終端發(fā)送請(qǐng)求
curl http://localhost:8080/albums
新增數(shù)據(jù)項(xiàng)
使用同樣的方式,在服務(wù)器端編寫POST請(qǐng)求接收客戶端數(shù)據(jù)新增數(shù)據(jù)項(xiàng)。跟之前Get請(qǐng)求稍微不同的是,該請(qǐng)求需要從request對(duì)象中解析出Body信息
處理函數(shù)
// postAlbums adds an album from JSON received in the request body. func postAlbums(c *gin.Context) { var newAlbum album // 調(diào)用BindJSON方法將數(shù)據(jù)解析到 newAlbum變量中 if err := c.BindJSON(&newAlbum); err != nil { return } // 將數(shù)據(jù)追加到內(nèi)存數(shù)組中 albums = append(albums, newAlbum) c.IndentedJSON(http.StatusCreated, newAlbum) }
路由處理
func main() { router := gin.Default() router.GET("/albums", getAlbums) router.POST("/albums", postAlbums) router.Run("localhost:8080") }
運(yùn)行服務(wù)
$ go run .
發(fā)送客戶端請(qǐng)求
$ curl http://localhost:8080/albums \ --include \ --header "Content-Type: application/json" \ --request "POST" \ --data '{"id": "4","title": "The Modern Sound of Betty Carter","artist": "Betty Carter","price": 49.99}'
此時(shí),在調(diào)用獲取數(shù)據(jù)列表的接口,必須返回4個(gè)數(shù)據(jù)了
返回指定數(shù)據(jù)
當(dāng)客戶端以GET請(qǐng)求方式調(diào)用 **/albums/[id]**路徑,服務(wù)端需要返回指定ID的數(shù)據(jù)詳情。此時(shí)該ID是由客戶端動(dòng)態(tài)指定的,接下來(lái)看看如何實(shí)現(xiàn)
處理函數(shù)
// getAlbumByID locates the album whose ID value matches the id // parameter sent by the client, then returns that album as a response. func getAlbumByID(c *gin.Context) { id := c.Param("id") // Loop over the list of albums, looking for // an album whose ID value matches the parameter. for _, a := range albums { if a.ID == id { c.IndentedJSON(http.StatusOK, a) return } } c.IndentedJSON(http.StatusNotFound, gin.H{"message": "album not found"}) }
路由匹配
func main() { router := gin.Default() router.GET("/albums", getAlbums) router.GET("/albums/:id", getAlbumByID) router.POST("/albums", postAlbums) router.Run("localhost:8080") }
運(yùn)行服務(wù)
$ go run .
客戶端請(qǐng)求
$ curl http://localhost:8080/albums/2
完整代碼
package main import ( "net/http" "github.com/gin-gonic/gin" ) // album represents data about a record album. type album struct { ID string `json:"id"` Title string `json:"title"` Artist string `json:"artist"` Price float64 `json:"price"` } // albums slice to seed record album data. var albums = []album{ {ID: "1", Title: "Blue Train", Artist: "John Coltrane", Price: 56.99}, {ID: "2", Title: "Jeru", Artist: "Gerry Mulligan", Price: 17.99}, {ID: "3", Title: "Sarah Vaughan and Clifford Brown", Artist: "Sarah Vaughan", Price: 39.99}, } func getAlbums(c *gin.Context) { c.IndentedJSON(http.StatusOK, albums) } // postAlbums adds an album from JSON received in the request body. func postAlbums(c *gin.Context) { var newAlbum album // Call BindJSON to bind the received JSON to // newAlbum. if err := c.BindJSON(&newAlbum); err != nil { return } // Add the new album to the slice. albums = append(albums, newAlbum) c.IndentedJSON(http.StatusCreated, newAlbum) } // getAlbumByID locates the album whose ID value matches the id // parameter sent by the client, then returns that album as a response. func getAlbumByID(c *gin.Context) { id := c.Param("id") // Loop over the list of albums, looking for // an album whose ID value matches the parameter. for _, a := range albums { if a.ID == id { c.IndentedJSON(http.StatusOK, a) return } } c.IndentedJSON(http.StatusNotFound, gin.H{"message": "album not found"}) } func main() { router := gin.Default() router.GET("/albums", getAlbums) router.POST("/albums", postAlbums) router.GET("/albums/:id", getAlbumByID) router.Run("localhost:8080") }
到此這篇關(guān)于Golang使用Gin創(chuàng)建Restful API的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Golang 創(chuàng)建Restful API內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一文詳解Golang協(xié)程調(diào)度器scheduler
這篇文章主要介紹了一文詳解Golang協(xié)程調(diào)度器scheduler,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-07-07淺析Go語(yǔ)言容器之?dāng)?shù)組和切片的使用
在?Java?的核心庫(kù)中,集合框架可謂鼎鼎大名:Array?、List、Set等等,隨便拎一個(gè)出來(lái)都值得開發(fā)者好好學(xué)習(xí)如何使用甚至是背后的設(shè)計(jì)源碼。雖然Go語(yǔ)言沒有如此豐富的容器類型,但也有一些基本的容器供開發(fā)者使用,接下來(lái)讓我們認(rèn)識(shí)一下這些容器類型吧2022-11-11用Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)實(shí)現(xiàn)Web服務(wù)之項(xiàng)目介紹
從本節(jié)開始將從后端到前端一步一步實(shí)現(xiàn)一個(gè)Go語(yǔ)言Web服務(wù),后端除了MySQL驅(qū)動(dòng),全部使用Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)來(lái)實(shí)現(xiàn)一個(gè)小型項(xiàng)目,本篇將簡(jiǎn)單的介紹一下項(xiàng)目開發(fā)要準(zhǔn)備的流程,感興趣的同學(xué)可以閱讀一下2023-05-05關(guān)于Gin框架中的Cookie和Session的使用方法
為了實(shí)現(xiàn)跨請(qǐng)求的數(shù)據(jù)共享,我們可以使用Cookie和Session,本文將結(jié)合實(shí)際案例,詳細(xì)介紹在Go語(yǔ)言的Gin框架中如何使用Cookie和Session,并通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下2024-10-10Go語(yǔ)言中常量和變量的定義、使用規(guī)范及常見應(yīng)用場(chǎng)景
每一門語(yǔ)言都會(huì)有常量的定義,變量的定義,以及基于這些定義的運(yùn)算,下面這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言中常量和變量的定義、使用規(guī)范及常見應(yīng)用場(chǎng)景的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-06-06