开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 7 天,点击查看活动详情
目标:构建Http服务器,处理get和post请求
Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架
准备工作
定义一个struct,用来存储数据;
像是json:"id"
这种标签,指定了序列化为json数据时的字段名,没有的话就会使用结构体字段的大写名称(这样就不太符合JSON的格式了);
type album struct {
ID string `json:"id"`
Title string `json:"title"`
Artist string `json:"artist"`
Price float64 `json:"price"`
}
定义切片,提供数据
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},
}
写一个GET请求的处理器,返回所有数据
当客户端发出GET /albums的请求时,以json格式返回数据;
gin.Context
带有请求参数,负责验证和序列化json数据等等;c.IndentedJSON
将数据序列化成json,并添加到response中去;第一个参数是想发送给客户端的HTTP状态码,第二个参数是要序列化成json的数据;- 可以替换成
c.JSON
来发送更紧凑的json数据
func getAlbums(c *gin.Context) {
c.IndentedJSON(http.StatusOK, albums)
}
- 初始化一个gin路由器;
- 将/albums路径上的GET方法与
getAlbums
函数连接起来; - 将路由器连接到http.Server上,并启动服务器;
func main(){
router := gin.Default()
router.GET("/albums", getAlbums)
router.Run("localhost:8080")
}
go run .
运行服务器;再打开另一个窗口运行curl http://localhost:8080/albums
添加一个POST请求的处理器
当客户端向/albums发出POST请求时,把请求体中的数据添加到现有切片中;
- 添加一个处理POST请求的函数;
- 用
c.BindJSON
将请求体中的数据绑定到newAlbum
变量; - 将数据添加到切片中;
- 将HTTP状态码201 http.StatusCreated 和添加的数据添加到respons中;
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
}
albums = append(albums, newAlbum)
c.IndentedJSON(http.StatusCreated, newAlbum)
}
将/albums路径上的POST方法与postAlbums函数连接起来;main函数中添加以下语句;
router.POST("/albums", postAlbums)
- 运行
go run .
- 使用另一个窗口运行:
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}'
结果:
添加一个处理程序来返回一个特定的数据
当客户端发出GET/albums/[id]
的请求时,返回ID与路径参数id相匹配的数据。
- 使用
gin.Context.Param
来检索URL中的id路径参数; - 当把这个处理程序映射到一个路径时,这个路径中将包括一个参数的占位符;
- 循环切片中的数据,寻找ID与参数id匹配的数据;如果找到了,将这条数据序列化成json数据,并返回200状态码;如果没找到,返回404状态码
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"})
}
将/albums/:id
路径与getAlbumByID
函数连接起来;
在Gin中,路径中某个item前面的冒号表示这是一个路径参数;
router.GET("/albums/:id", getAlbumByID)
数据不存在时
curl http://localhost:8080/albums/5
{
"message": "album not found"
}
至此,一个简单的RESTful web service就完成了。