首页  »   Go

2018 Golang Update(二)REST API with Gin

网友分享于:2018-03-19  浏览:0次
2018 Golang Update(2)REST API with Gin
2018 Golang Update(2)REST API with Gin

Install Gin
>go get github.com/gin-gonic/gin

Install govendor
>go get github.com/kardianos/govendor
Add current path to go path
export GOPATH="/Users/carl/work/easy/easygo:/Users/carl/work/sillycat/monitor-water/restful_go_api"

Create the directory
>mkdir -p src/com/sillycat/restful_go_api

go to that working directory
>cd /Users/carl/work/sillycat/monitor-water/restful_go_api/src/com/sillycat/restful_go_api

I am using Mac Pro, install with brew
>brew install govendor
Check the version
>govendor --version
v1.0.9

Init the Project
>govendor init

Fetch gin
>govendor fetch github.com/gin-gonic/gin@v1.2

Copy the latest sample here
>curl https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go > main.go

Run the sample
>go run main.go

Build that like this
>go install com/sillycat/restful_go_api

Run it like this
>bin/restful_go_api
[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.setupRouter.func1 (3 handlers)
[GIN-debug] GET    /user/:name               --> main.setupRouter.func2 (3 handlers)
[GIN-debug] POST   /admin                    --> main.setupRouter.func3 (4 handlers)

I reactor the structure a little, code is in project monitor-water/restful_go_api

Read me is as follow:
#restful_go_api

Prepare the library
>go get github.com/gin-gonic/gin

How to Build
>go install sillycat.com/restful_go_api

How to Build for Linux
>env GOOS=linux GOARCH=amd64 go build -o bin/restful_go_api_linux -v sillycat.com/restful_go_api

How to Run
>bin/restful_go_api

How to Test
>go test sillycat.com/restful_go_api

restful_go_api/src/sillycat.com/main.go
package main

import "github.com/gin-gonic/gin"
import "sillycat.com/restful_go_api/waterrecord"

var DB = make(map[string]string)

func SetupRouter() *gin.Engine {
    // Disable Console Color
    // gin.DisableConsoleColor()
    router := gin.Default()

    // Ping test
    router.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })

    v1 := router.Group("api/v1")
    {
        v1.GET("/waterrecords", waterrecord.GetWaterRecords)
        v1.GET("/waterrecords/:id", waterrecord.GetWaterRecord)
        v1.POST("/waterrecords", waterrecord.PostWaterRecord)
        v1.PUT("/waterrecords/:id", waterrecord.UpdateWaterRecord)
        v1.DELETE("/waterrecords/:id", waterrecord.DeleteWaterRecord)
    }

    return router
}

func main() {
    router := SetupRouter()
    // Listen and Server in 0.0.0.0:8080
    router.Run(":8080")
}

restful_go_api/src/sillycat.com/restful_go_api/waterrecord/waterrecord.go
package waterrecord

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

func GetWaterRecords(c *gin.Context) {
    c.JSON(200, gin.H{"ok": "GET api/v1/waterrecords"})
}

func GetWaterRecord(c *gin.Context) {
    c.JSON(200, gin.H{"ok": "GET api/v1/waterrecords/1"})
}

func PostWaterRecord(c *gin.Context) {
    c.JSON(200, gin.H{"ok": "POST api/v1/waterrecords"})

}

func UpdateWaterRecord(c *gin.Context) {
    c.JSON(200, gin.H{"ok": "PUT api/v1/waterrecords/1"})

}

func DeleteWaterRecord(c *gin.Context) {
    c.JSON(200, gin.H{"ok": "DELETE api/v1/waterrecords/1"})
}

restful_go_api/src/sillycat.com/restful_go_api/main_test.go
package main

import (
    "bytes"
    "github.com/gin-gonic/gin"
    "net/http"
    "net/http/httptest"
    "testing"
)

func TestGetInstruction(t *testing.T) {
    gin.SetMode(gin.TestMode)
    testRouter := SetupRouter()

    req, err := http.NewRequest("GET", "/api/v1/waterrecords/1", nil)
    if err != nil {
        t.Errorf("Get hearteat failed with error %d.", err)
    }

    resp := httptest.NewRecorder()
    testRouter.ServeHTTP(resp, req)

    if resp.Code != 200 {
        t.Errorf("/api/v1/waterrecords failed with error code %d.", resp.Code)
    }
}

func TestGetInstructions(t *testing.T) {
    gin.SetMode(gin.TestMode)
    testRouter := SetupRouter()

    req, err := http.NewRequest("GET", "/api/v1/waterrecords", nil)
    if err != nil {
        t.Errorf("Get hearteat failed with error %d.", err)
    }

    resp := httptest.NewRecorder()
    testRouter.ServeHTTP(resp, req)

    if resp.Code != 200 {
        t.Errorf("/api/v1/waterrecords failed with error code %d.", resp.Code)
    }
}

func TestPostInstruction(t *testing.T) {
    gin.SetMode(gin.TestMode)
    testRouter := SetupRouter()

    body := bytes.NewBuffer([]byte("{\"event_status\": \"83\", \"event_name\": \"100\"}"))

    req, err := http.NewRequest("POST", "/api/v1/waterrecords", body)
    req.Header.Set("Content-Type", "application/json")
    if err != nil {
        t.Errorf("Post hearteat failed with error %d.", err)
    }

    resp := httptest.NewRecorder()
    testRouter.ServeHTTP(resp, req)

    if resp.Code != 201 {
        t.Errorf("/api/v1/waterrecords failed with error code %d.", resp.Code)
    }
}

func TestPutInstruction(t *testing.T) {
    gin.SetMode(gin.TestMode)
    testRouter := SetupRouter()

    body := bytes.NewBuffer([]byte("{\"event_status\": \"83\", \"event_name\": \"100\"}"))

    req, err := http.NewRequest("PUT", "/api/v1/waterrecords/1", body)
    req.Header.Set("Content-Type", "application/json")
    if err != nil {
        t.Errorf("Put hearteat failed with error %d.", err)
    }

    resp := httptest.NewRecorder()
    testRouter.ServeHTTP(resp, req)

    if resp.Code != 200 {
        t.Errorf("/api/v1/waterrecords failed with error code %d.", resp.Code)
    }
}



Database Layer
https://github.com/go-gorp/gorp
http://hao.jobbole.com/gorp/
https://awesome-go.com/#orm
https://github.com/go-xorm/xorm
http://xorm.io/

I will check and use xorm to see if it works.

References:
https://github.com/gin-gonic/gin
https://github.com/avelino/awesome-go#web-frameworks
https://github.com/kardianos/govendor
http://himarsh.org/build-restful-api-microservice-with-go/
https://github.com/marshallshen/instructions

https://coolshell.cn/articles/8460.html
https://coolshell.cn/articles/8489.html
https://stackoverflow.com/questions/30885098/go-local-import-in-non-local-package

相关解决方案

最新解决方案