一、安裝依賴
安裝gin和golang mysql driver,如下:
go get "github.com/go-sql-driver/mysql" go get "github.com/gin-gonic/gin"
二、創建測試用的數據庫
安裝完mysql-server包后,啟動並配置用戶名密碼后,使用 CREATE DATABASE gotest 創建測試數據庫。數據庫下新建person 表,該表可以通過命令行進行創建,也可以使用golang程序連接測試創建,代碼如下:
package main import ( "database/sql" "fmt" _ "github.com/go-sql-driver/mysql" ) func main() { db, err := sql.Open("mysql", "root:passapp@tcp(127.0.0.1:3306)/gotest") if err != nil { fmt.Print(err.Error()) } defer db.Close() // make sure connection is available err = db.Ping() if err != nil { fmt.Print(err.Error()) } stmt, err := db.Prepare("CREATE TABLE person (id int NOT NULL AUTO_INCREMENT, first_name varchar(40), last_name varchar(40), PRIMARY KEY (id));") if err != nil { fmt.Println(err.Error()) } _, err = stmt.Exec() if err != nil { fmt.Print(err.Error()) } else { fmt.Printf("Person Table successfully migrated....") } }
上面使用了db.Ping()函數進行測試數據庫能否正常連接。
三、CURL實現
一個基礎的API一般涉及如下幾個類型的APi操作模式:
GET
POST
PUT
DELETE
使用gin.Default()可以創建一個默認路由。接下實現一個handle對象,其有兩個參數,第一個參數是URL,第二個是gin.Context對象。具體代碼如下:
package main import ( "bytes" "database/sql" "fmt" "net/http" "github.com/gin-gonic/gin" _ "github.com/go-sql-driver/mysql" ) func main() { db, err := sql.Open("mysql", "root:passapp@tcp(127.0.0.1:3306)/gotest") if err != nil { fmt.Print(err.Error()) } defer db.Close() // make sure connection is available err = db.Ping() if err != nil { fmt.Print(err.Error()) } type Person struct { Id int First_Name string Last_Name string } router := gin.Default() // GET a person detail router.GET("/person/:id", func(c *gin.Context) { var ( person Person result gin.H ) id := c.Param("id") row := db.QueryRow("select id, first_name, last_name from person where id = ?;", id) err = row.Scan(&person.Id, &person.First_Name, &person.Last_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) }) // GET all persons router.GET("/persons", func(c *gin.Context) { var ( person Person persons []Person ) rows, err := db.Query("select id, first_name, last_name from person;") if err != nil { fmt.Print(err.Error()) } for rows.Next() { err = rows.Scan(&person.Id, &person.First_Name, &person.Last_Name) persons = append(persons, person) if err != nil { fmt.Print(err.Error()) } } defer rows.Close() c.JSON(http.StatusOK, gin.H{ "result": persons, "count": len(persons), }) }) // POST new person details router.POST("/person", func(c *gin.Context) { var buffer bytes.Buffer first_name := c.PostForm("first_name") last_name := c.PostForm("last_name") stmt, err := db.Prepare("insert into person (first_name, last_name) values(?,?);") if err != nil { fmt.Print(err.Error()) } _, err = stmt.Exec(first_name, last_name) if err != nil { fmt.Print(err.Error()) } // Fastest way to append strings buffer.WriteString(first_name) buffer.WriteString(" ") buffer.WriteString(last_name) defer stmt.Close() name := buffer.String() c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf(" %s successfully created", name), }) }) // PUT - update a person details router.PUT("/person", func(c *gin.Context) { var buffer bytes.Buffer id := c.Query("id") first_name := c.PostForm("first_name") last_name := c.PostForm("last_name") stmt, err := db.Prepare("update person set first_name= ?, last_name= ? where id= ?;") if err != nil { fmt.Print(err.Error()) } _, err = stmt.Exec(first_name, last_name, id) if err != nil { fmt.Print(err.Error()) } // Fastest way to append strings buffer.WriteString(first_name) buffer.WriteString(" ") buffer.WriteString(last_name) defer stmt.Close() name := buffer.String() c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf("Successfully updated to %s", name), }) }) // Delete resources router.DELETE("/person", func(c *gin.Context) { id := c.Query("id") stmt, err := db.Prepare("delete from person where id= ?;") if err != nil { fmt.Print(err.Error()) } _, err = stmt.Exec(id) if err != nil { fmt.Print(err.Error()) } c.JSON(http.StatusOK, gin.H{ "message": fmt.Sprintf("Successfully deleted user: %s", id), }) }) router.Run(":3000") }
