gin在Golang開發(fā)中的應(yīng)用實(shí)例
機(jī)囂人小朋
發(fā)布于 東京都 2018-09-29 · 4.6w瀏覽 2贊

Gin是一個用Go(Golang)編寫的HTTP Web框架。 它具有類似Martini的API,具有更好的性能 - 速度提高了40倍。


安裝

要安裝Gin軟件包,您需要先安裝Go并設(shè)置Go工作區(qū)。

  1. 下載并安裝它:

  $ go get -u github.com/gin-gonic/gin
  1. 在代碼中導(dǎo)入它:

  導(dǎo)入 “ github.com/gin-gonic/gin ”
  1. (可選)導(dǎo)入net/http 。 例如,如果使用諸如http.StatusOK常量, http.StatusOK 。

  導(dǎo)入 “ net / http ”

 使用像Govendor這樣的第三方工具

  1. go get govendor

  $ go get github.com/kardianos/govendor
  1. 在里面創(chuàng)建你的項(xiàng)目文件夾和cd

  $ mkdir -p $ GOPATH /src/github.com/myusername/project && cd “ $ _ ”
  1. 供應(yīng)商初始化您的項(xiàng)目并添加Gin

  $ govendor init $ govendor fetch github.com/gin-gonic/gin@v1.3
  1. 復(fù)制項(xiàng)目中的起始模板

  $ curl https://raw.githubusercontent.com/gin-gonic/gin/master/examples/basic/main.go > main.go
  1. 運(yùn)行您的項(xiàng)目

  $ go run main.go

 條件

Gin需要Go 1.6或更高版本,很快就會只能在高于Go 1.7的環(huán)境下使用

 快速開始

  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() // listen and serve on 0.0.0.0:8080}

 基準(zhǔn)測試

Gin使用自定義版本的HttpRouter

查看所有基準(zhǔn)測試

基準(zhǔn)名稱(1)(2)(3)(4)
BenchmarkGin_GithubAll300004837500
BenchmarkAce_GithubAll1000013405913792167
BenchmarkBear_GithubAll500053444586448943
BenchmarkBeego_GithubAll300059244474705812
BenchmarkBone_GithubAll20069573086987848453
BenchmarkDenco_GithubAll1000015881920224167
BenchmarkEcho_GithubAll100001547006496203
BenchmarkGocraftWeb_GithubAll30005708061316561686
BenchmarkGoji_GithubAll200081803456112334
BenchmarkGojiv2_GithubAll200012139732747683712
BenchmarkGoJsonRest_GithubAll20007857961343712737
BenchmarkGoRestful_GithubAll30052381886896724519
BenchmarkGorillaMux_GithubAll100102577262118402272
BenchmarkHttpRouter_GithubAll2000010541413792167
BenchmarkHttpTreeMux_GithubAll1000031993465856671
BenchmarkKocha_GithubAll1000020944223304843
BenchmarkLARS_GithubAll200006256500
BenchmarkMacaron_GithubAll200011612702041942000
BenchmarkMartini_GithubAll20099917132265492325
BenchmarkPat_GithubAll2005590793149956827435
BenchmarkPossum_GithubAll1000031976884448609
BenchmarkR2router_GithubAll1000030513477328979
BenchmarkRivet_GithubAll1000013213416272167
BenchmarkTango_GithubAll3000552754638261618
BenchmarkTigerTonic_GithubAll100014394832391045374
BenchmarkTraffic_GithubAll10011383067265932921848
BenchmarkVulcan_GithubAll500039425319894609
  • (1):在恒定時間內(nèi)實(shí)現(xiàn)總重復(fù),更高意味著更自信的結(jié)果

  • (2):單次重復(fù)持續(xù)時間(ns / op),越低越好

  • (3):堆內(nèi)存(B / op),越低越好

  • (4):每次重復(fù)的平均分配(allocs / op),越低越好

 API示例

 使用GET,POST,PUT,PATCH,DELETE和OPTIONS

func main() {	// Disable Console Color
	// gin.DisableConsoleColor()

	// Creates a gin router with default middleware:
	// logger and recovery (crash-free) middleware
	router := gin.Default()

	router.GET("/someGet", getting)
	router.POST("/somePost", posting)
	router.PUT("/somePut", putting)
	router.DELETE("/someDelete", deleting)
	router.PATCH("/somePatch", patching)
	router.HEAD("/someHead", head)
	router.OPTIONS("/someOptions", options)	// By default it serves on :8080 unless a
	// PORT environment variable was defined.
	router.Run()	// router.Run(":3000") for a hard coded port}

 路徑中的參數(shù)

func main() {	router := gin.Default()	// This handler will match /user/john but will not match /user/ or /user
	router.GET("/user/:name", func(c *gin.Context) {		name := c.Param("name")
		c.String(http.StatusOK, "Hello %s", name)
	})	// However, this one will match /user/john/ and also /user/john/send
	// If no other routers match /user/john, it will redirect to /user/john/
	router.GET("/user/:name/*action", func(c *gin.Context) {		name := c.Param("name")		action := c.Param("action")		message := name + " is " + action
		c.String(http.StatusOK, message)
	})

	router.Run(":8080")
}

 查詢字符串參數(shù)


func main() {	router := gin.Default()	// Query string parameters are parsed using the existing underlying request object.
	// The request responds to a url matching:  /welcome?firstname=Jane&lastname=Doe
	router.GET("/welcome", func(c *gin.Context) {		firstname := c.DefaultQuery("firstname", "Guest")		lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")

		c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
	})
	router.Run(":8080")
}

復(fù)合表單處理

func main() {	router := gin.Default()

	router.POST("/form_post", func(c *gin.Context) {		message := c.PostForm("message")		nick := c.DefaultPostForm("nick", "anonymous")

		c.JSON(200, gin.H{			"status":  "posted",			"message": message,			"nick":    nick,
		})
	})
	router.Run(":8080")
}

查詢+提交

POST /post?id=1234&page=1 HTTP/1.1
Content-Type: application/x-www-form-urlencoded

name=manu&message=this_is_great
func main() {	router := gin.Default()

	router.POST("/post", func(c *gin.Context) {		id := c.Query("id")		page := c.DefaultQuery("page", "0")		name := c.PostForm("name")		message := c.PostForm("message")

		fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
	})
	router.Run(":8080")
}
id: 1234; page: 1; name: manu; message: this_is_great

將查詢串及提交屬性轉(zhuǎn)換為map

POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
Content-Type: application/x-www-form-urlencoded

names[first]=thinkerou&names[second]=tianou
func main() {	router := gin.Default()

	router.POST("/post", func(c *gin.Context) {		ids := c.QueryMap("ids")		names := c.PostFormMap("names")

		fmt.Printf("ids: %v; names: %v", ids, names)
	})
	router.Run(":8080")
}
ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]

上傳文件

單文件

func main() {	router := gin.Default()	// Set a lower memory limit for multipart forms (default is 32 MiB)
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	router.POST("/upload", func(c *gin.Context) {		// single file
		file, _ := c.FormFile("file")
		log.Println(file.Filename)		// Upload the file to specific dst.
		// c.SaveUploadedFile(file, dst)

		c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
	})
	router.Run(":8080")
}

多文件上傳

func main() {	router := gin.Default()	// Set a lower memory limit for multipart forms (default is 32 MiB)
	// router.MaxMultipartMemory = 8 << 20  // 8 MiB
	router.POST("/upload", func(c *gin.Context) {		// Multipart form
		form, _ := c.MultipartForm()		files := form.File["upload[]"]		for _, file := range files {
			log.Println(file.Filename)			// Upload the file to specific dst.
			// c.SaveUploadedFile(file, dst)
		}
		c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
	})
	router.Run(":8080")
}

使用 curl進(jìn)行模擬:

curl -X POST http://localhost:8080/upload \
  -F "upload[]=@/Users/appleboy/test1.zip" \
  -F "upload[]=@/Users/appleboy/test2.zip" \
  -H "Content-Type: multipart/form-data"

組別化路由

func main() {	router := gin.Default()	// Simple group: v1
	v1 := router.Group("/v1")
	{
		v1.POST("/login", loginEndpoint)
		v1.POST("/submit", submitEndpoint)
		v1.POST("/read", readEndpoint)
	}	// Simple group: v2
	v2 := router.Group("/v2")
	{
		v2.POST("/login", loginEndpoint)
		v2.POST("/submit", submitEndpoint)
		v2.POST("/read", readEndpoint)
	}

	router.Run(":8080")
}

純凈版的Gin對象

使用

r := gin.New()

替代

// Default With the Logger and Recovery middleware already attached
r := gin.Default()

使用中間件

func main() {	// Creates a router without any middleware by default
	r := gin.New()	// Global middleware
	// Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
	// By default gin.DefaultWriter = os.Stdout
	r.Use(gin.Logger())	// Recovery middleware recovers from any panics and writes a 500 if there was one.
	r.Use(gin.Recovery())	// Per route middleware, you can add as many as you desire.
	r.GET("/benchmark", MyBenchLogger(), benchEndpoint)	// Authorization group
	// authorized := r.Group("/", AuthRequired())
	// exactly the same as:
	authorized := r.Group("/")	// per group middleware! in this case we use the custom created
	// AuthRequired() middleware just in the "authorized" group.
	authorized.Use(AuthRequired())
	{
		authorized.POST("/login", loginEndpoint)
		authorized.POST("/submit", submitEndpoint)
		authorized.POST("/read", readEndpoint)		// nested group
		testing := authorized.Group("testing")
		testing.GET("/analytics", analyticsEndpoint)
	}	// Listen and serve on 0.0.0.0:8080
	r.Run(":8080")
}

日志書寫

func main() {    // Disable Console Color, you don't need console color when writing the logs to file.
    gin.DisableConsoleColor()    // Logging to a file.
    f, _ := os.Create("gin.log")
    gin.DefaultWriter = io.MultiWriter(f)    // Use the following code if you need to write the logs to file and console at the same time.
    // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)

    router := gin.Default()
    router.GET("/ping", func(c *gin.Context) {
        c.String(200, "pong")
    })

    router.Run(":8080")
}

還有例如類型實(shí)體綁定,查詢條件綁定等操作,不常用,此處略去

機(jī)囂人小朋
我是小朋,不是小明
瀏覽 4.6w
2
相關(guān)推薦
最新評論
贊過的人 2
評論加載中...

暫無評論,快來評論吧!