生命不止,继续 go go go !!!

先插播一条广告,给你坚持学习golang的理由:

《2017 软件开发薪酬调查:Go 和 Scala 是最赚钱的语言》

言归正传!

之前写过使用golang实现简单的restful api相关的博客:

Go实战–实现简单的restful api(The way to go)

其中,使用了github.com/gorilla/mux,今天要跟大家介绍的是gin-gonic/gin。

gin-gonic/gin

介绍:

Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API with much better performance – up to 40 times faster. If you need smashing performance, get yourself some Gin.

github地址:

https://github.com/gin-gonic/gin

获取:

go get github.com/gin-gonic/gin

1

例子:

package main

import "github.com/gin-gonic/gin"

func main() {

r := gin.Default()

r.GET("/ping", func(c *gin.Context) {

c.JSON(200, gin.H{

"message": "pong",

})

})

r.Run()

}

1

2

3

4

5

6

7

8

9

10

11

12

13

运行:

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.

- using env: export GIN_MODE=release

- using code: gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET /ping --> main.main.func1 (3 handlers)

[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default

[GIN-debug] Listening and serving HTTP on :8080

1

2

3

4

5

6

7

8

通过浏览器访问:

http://localhost:8080/ping

// 20170808110257

// http://localhost:8080/ping

{

"message": "pong"

}

1

2

3

4

5

6

全局设置环境:

gin.SetMode(gin.DebugMode)

1

gin.SetMode(gin.ReleaseMode)

1

获得路由实例:

r := gin.Default()

1

构建restful api

创建五个routes:

package main

import (

"github.com/gin-gonic/gin"

)

func main() {

router := gin.Default()

v1 := router.Group("/api/v1/userinfo")

{

v1.POST("/", CreateUser)

v1.GET("/", FetchAllUsers)

v1.GET("/:id", FetchSingleUser)

v1.PUT("/:id", UpdateUser)

v1.DELETE("/:id", DeleteUser)

}

router.Run()

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

下面我们要使用gin+mysql构建restful api。

如果对于golang中的MySQL不够熟悉的话,可以看看我之前写过的博文:

Go实战–go语言操作MySQL数据库(go-sql-driver/mysql)

先实现一个简单的根据id来FetchSingleUser吧:

我们事先通过命令行创建了user_info表以及一行数据,id=2, name=wangshubo

开始golang程序:

定义结构体:

type Person struct {

Id int

Name string

}

1

2

3

4

check函数:

func checkErr(err error) {

if err != nil {

panic(err)

}

}

1

2

3

4

5

FetchSingleUser方法:

我们要返回json, gin对json也进行了封装,所以不再需要我们提供类似encoding/json之类的package。

func FetchSingleUser(c *gin.Context) {

id := c.Param("id")

db, err := sql.Open("mysql", "root:wangshubo@/test?charset=utf8")

checkErr(err)

defer db.Close()

err = db.Ping()

checkErr(err)

var (

person Person

result gin.H

)

row := db.QueryRow("select id, name from user_info where id = ?;", id)

err = row.Scan(&person.Id, &person.Name)

if err != nil {

// If no results send null

result = gin.H{

"result": nil,

"count": 0,

}

} else {

result = gin.H{

"result": person,

"count": 1,

}

}

c.JSON(http.StatusOK, result)

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

浏览器访问:

http://localhost:8080/api/v1/userinfo/1

// 20170808141904

// http://localhost:8080/api/v1/userinfo/1

{

"count": 0,

"result": null

}

1

2

3

4

5

6

7

浏览器访问:

http://localhost:8080/api/v1/userinfo/2

// 20170808141940

// http://localhost:8080/api/v1/userinfo/2

{

"count": 1,

"result": {

"Id": 2,

"Name": "wangshubo"

}

}

1

2

3

4

5

6

7

8

9

10

gin输出log:

[GIN] 2017/08/08 - 14:19:03 | 200 | 16.0127ms | ::1 | GET /api/v1/userinfo/1

[GIN] 2017/08/08 - 14:19:39 | 200 | 56.0381ms | ::1 | GET /api/v1/userinfo/2

1

2