Last active
February 20, 2021 21:13
-
-
Save asm-jaime/0bd3c294f4cb4f7a7775af6749de4b28 to your computer and use it in GitHub Desktop.
go gin mgo, gin+mongo+test example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"encoding/base64" | |
"fmt" | |
rand "math/rand" | |
"time" | |
"github.com/gin-gonic/gin" | |
mgo "gopkg.in/mgo.v2" | |
"gopkg.in/mgo.v2/bson" | |
) | |
// ========== random {{{ | |
var letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") | |
func rndStr(n int) string { | |
rnd_str := make([]rune, n) | |
for i := range rnd_str { | |
rnd_str[i] = letterRunes[rand.Intn(len(letterRunes))] | |
} | |
return string(rnd_str) | |
} | |
// RandToken generates a random @length token. | |
func RandToken(length int) string { | |
tbyte := make([]byte, length) | |
rand.Read(tbyte) | |
return base64.StdEncoding.EncodeToString(tbyte) | |
} // }}} | |
// ========== Data | |
type Data struct { | |
Id bson.ObjectId `form:"id" bson:"_id,omitempty"` | |
Data string `form:"data" bson:"data"` | |
} | |
// ========== MongoDB | |
type MongoDB struct { | |
Host string | |
Port string | |
Addrs string | |
Database string | |
EventTTLAfterEnd time.Duration | |
StdEventTTL time.Duration | |
Info *mgo.DialInfo | |
Session *mgo.Session | |
} | |
func (mongo *MongoDB) SetDefault() { // {{{ | |
mongo.Host = "localhost" | |
mongo.Addrs = "localhost:27017" | |
mongo.Database = "context" | |
mongo.EventTTLAfterEnd = 1 * time.Second | |
mongo.StdEventTTL = 20 * time.Minute | |
mongo.Info = &mgo.DialInfo{ | |
Addrs: []string{mongo.Addrs}, | |
Timeout: 60 * time.Second, | |
Database: mongo.Database, | |
} | |
} // }}} | |
func (mongo *MongoDB) Drop() (err error) { // {{{ | |
session := mongo.Session.Clone() | |
defer session.Close() | |
err = session.DB(mongo.Database).DropDatabase() | |
if err != nil { | |
return err | |
} | |
return nil | |
} // }}} | |
func (mongo *MongoDB) Init() (err error) { // {{{ | |
err = mongo.Drop() | |
if err != nil { | |
fmt.Printf("\n drop database error: %v\n", err) | |
} | |
data := Data{} | |
data.Data = rndStr(8) | |
err = mongo.PostData(&data) | |
return err | |
} // }}} | |
func (mongo *MongoDB) SetSession() (err error) { | |
mongo.Session, err = mgo.DialWithInfo(mongo.Info) | |
if err != nil { | |
mongo.Session, err = mgo.Dial(mongo.Host) | |
if err != nil { | |
return err | |
} | |
} | |
return err | |
} | |
// ========== model | |
func (mongo *MongoDB) GetData() (dates []Data, err error) { // {{{ | |
session := mongo.Session.Clone() | |
defer session.Close() | |
err = session.DB(mongo.Database).C("Data").Find(bson.M{}).All(&dates) | |
return dates, err | |
} // }}} | |
func (mongo *MongoDB) PostData(data *Data) (err error) { // {{{ | |
session := mongo.Session.Clone() | |
defer session.Close() | |
err = session.DB(mongo.Database).C("Data").Insert(&data) | |
return err | |
} // }}} | |
// ========== controller | |
func getData(c *gin.Context) { // {{{ | |
mongo, ok := c.Keys["mongo"].(*MongoDB) | |
if !ok { | |
c.JSON(400, gin.H{"message": "can't reach db", "body": nil}) | |
} | |
data, err := mongo.GetData() | |
// fmt.Printf("\ndata: %v, ok: %v\n", data, ok) | |
if err != nil { | |
c.JSON(400, gin.H{"message": "can't get data from database", "body": nil}) | |
} else { | |
c.JSON(200, gin.H{"message": "get data sucess", "body": data}) | |
} | |
} // }}} | |
func postData(c *gin.Context) { // {{{ | |
mongo, ok := c.Keys["mongo"].(*MongoDB) | |
if !ok { | |
c.JSON(400, gin.H{"message": "can't connect to db", "body": nil}) | |
} | |
var req Data | |
err := c.Bind(&req) | |
if err != nil { | |
c.JSON(400, gin.H{"message": "Incorrect data", "body": nil}) | |
return | |
} else { | |
err := mongo.PostData(&req) | |
if err != nil { | |
c.JSON(400, gin.H{"message": "error post to db", "body": nil}) | |
} | |
c.JSON(200, gin.H{"message": "post data sucess", "body": req}) | |
} | |
} // }}} | |
// ========== middleware | |
func MiddleDB(mongo *MongoDB) gin.HandlerFunc { | |
return func(c *gin.Context) { | |
err := mongo.SetSession() | |
if err != nil { | |
c.Abort() | |
} else { | |
c.Set("mongo", mongo) | |
c.Next() | |
} | |
} | |
} | |
// ========== start router | |
func SetupRouter() *gin.Engine { | |
mongo := MongoDB{} | |
mongo.SetDefault() | |
router := gin.Default() | |
router.Use(gin.Logger()) | |
router.Use(gin.Recovery()) | |
router.Use(MiddleDB(&mongo)) | |
router.GET("/data", getData) | |
router.POST("/data", postData) | |
return router | |
} | |
func main() { | |
router := SetupRouter() | |
router.Run() | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bytes" | |
"fmt" | |
"net/http" | |
"net/http/httptest" | |
"net/url" | |
"sync" | |
"testing" | |
) | |
func TestGetPostData(t *testing.T) { | |
fmt.Println("start router") | |
testRouter := SetupRouter() | |
postValues := url.Values{} | |
postValues.Set("data", rndStr(4)) | |
postDataStr := postValues.Encode() | |
postDataBytes := []byte(postDataStr) | |
postBytesReader := bytes.NewReader(postDataBytes) | |
req, err := http.NewRequest("GET", "/data", nil) | |
post, err := http.NewRequest("POST", "/data", postBytesReader) | |
if err != nil { | |
fmt.Println(err) | |
} | |
wg := &sync.WaitGroup{} | |
for count := 0; count < 2; count++ { | |
wg.Add(1) | |
go func() { | |
defer wg.Done() | |
response := httptest.NewRecorder() | |
testRouter.ServeHTTP(response, req) | |
testRouter.ServeHTTP(response, post) | |
fmt.Println(response.Body) | |
}() | |
} | |
wg.Wait() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment