golang构建RESTful API

一、安装依赖

安装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")
}
原文地址:https://www.cnblogs.com/peteremperor/p/13944953.html