1. 程式人生 > >Gin框架系列02:路由與引數

Gin框架系列02:路由與引數

回顧

上一節我們用Gin框架快速搭建了一個GET請求的介面,今天來學習路由和引數的獲取。

請求動詞

熟悉RESTful的同學應該知道,RESTful是網路應用程式的一種設計風格和開發方式,每一個URI代表一種資源,客戶端通過POSTDELETEPUTGET四種請求方式來對資源做增刪改查的操作。

同樣的,Gin框架給我們提供的除這4種動詞外,還有PATCHOPTIONHEAD等,詳細內容可以檢視rentergroup.go檔案的IRoutes介面。

type IRoutes interface {
	Use(...HandlerFunc) IRoutes

	Handle(string, string, ...HandlerFunc) IRoutes
	Any(string, ...HandlerFunc) IRoutes
	GET(string, ...HandlerFunc) IRoutes
	POST(string, ...HandlerFunc) IRoutes
	DELETE(string, ...HandlerFunc) IRoutes
	PATCH(string, ...HandlerFunc) IRoutes
	PUT(string, ...HandlerFunc) IRoutes
	OPTIONS(string, ...HandlerFunc) IRoutes
	HEAD(string, ...HandlerFunc) IRoutes

	StaticFile(string, string) IRoutes
	Static(string, string) IRoutes
	StaticFS(string, http.FileSystem) IRoutes
}

因為RenterGroup實現了IRoutes定義的所有請求動詞,而且gin.Default返回的Engine型別繼承了RenterGroup,所以使用起來非常簡單,只需要通過gin.Default例項化物件,接下來所有的路由操作都通過該物件使用即可。

func main() {
	router := gin.Default()
	router.POST("/article", func(c *gin.Context) {
		c.String(200, "article post")
	})
	router.DELETE("/article", func(c *gin.Context) {
		c.String(200, "article delete")
	})
	router.PUT("/article", func(c *gin.Context) {
		c.String(200, "article put")
	})
	router.GET("/article", func(c *gin.Context) {
		c.String(200, "article get")
	})
	router.Run()
}

請求動詞的第一個引數是請求路徑,第二個引數是用於邏輯處理的函式,可以是匿名的或是其他地方定義的函式名。不同的請求動詞可以定義相同的路徑,只需要切換動詞就可以進入對應的處理邏輯。

curl -X PUT http://localhost:8080/article
curl -X POST http://localhost:8080/article
curl -X GET http://localhost:8080/article
curl -X DELETE http://localhost:8080/article

路由引數

GET請求有兩種,一種是在URL後加上?name=pingye,這種是有引數名的,另一種是在路徑中直接加上引數值/article/1

,這種沒有引數名,需要在程式碼中解析引數。

protocol://hostname:[port]/path/[query]#fragment

我們先來看路由攜帶引數值的玩法,這裡有一道題,怎麼利用Gin獲取下面連結的引數值1

實現方式非常簡單,只需要在路由中設定好佔位符:id,冒號為佔位符的標誌,冒號後面的引數名可以自定義,Gin會將路由與請求地址進行匹配,若匹配成功會將1賦值為佔位符:id,只需呼叫c.Param就可以獲取id的值。

router.GET("/article/:id", func(c *gin.Context) {
  id := c.Param("id")
  c.String(200, id)
})

但是,:id佔位符會存在一個問題,如果id引數值傳空就會有404的錯誤提示。

於是Gin提供了另一種佔位符*id,使用它就可以達到取空值的目的。

router.GET("/article/*id", func(c *gin.Context) {
  id := c.Param("id")
  c.String(200, id)
})

普通引數

除了路由攜帶引數值外,接下來看比較傳統的GET傳參方式。

http://localhost:8080/welcome?firstname=Jane&lastname=Doe

可以通過c.Queryc.DefaultQuery方法獲取問號後的引數。

router.GET("/welcome", func(c *gin.Context) {
   firstname := c.DefaultQuery("firstname", "pingyeaa")
   lastname := c.Query("lastname")
   c.String(200, firstname+" "+lastname)
})

這兩者最終都呼叫了GetQuery方法,唯一的區別是DefaultQuery做了預設值處理。

func (c *Context) DefaultQuery(key, defaultValue string) string {
	if value, ok := c.GetQuery(key); ok {
		return value
	}
	return defaultValue
}

func (c *Context) Query(key string) string {
	value, _ := c.GetQuery(key)
	return value
}

表單引數

從HTML提交過來的表單form內容同樣也可以輕鬆獲取。

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,
  })
})
curl -d "message=pingye" http://localhost:8080/form_post
{"message":"pingye","nick":"anonymous","status":"posted"}

陣列型別引數

有時候(例如複選框)前端頁面會傳來陣列型別的值,這種型別name相同,但儲存的內容不同。

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

依然是一個QueryMap方法就搞定,該方法預設返回map型別。

router.GET("/post", func(c *gin.Context) {
  ids := c.QueryMap("ids")
  c.String(200, ids["a"]+" "+ids["b"])
})
curl http://localhost:8080/post?ids[a]=pingye&ids[b]=hehe
pingye hehe

檔案上傳

一般情況下,檔案上傳會由前端直接傳給雲端儲存服務商,比如阿里雲、七牛雲等,比較少的場景會傳給自己的伺服器。為了避免書到用時方恨少的情況發生,我們來了解一下。

Gin提供了FormFile方法獲取檔案流,這個方法返回了一個FileHeader型別的變數,可以呼叫Filename屬性來檢視檔名。

type FileHeader struct {
   Filename string
   Header   textproto.MIMEHeader
   Size     int64

   content []byte
   tmpfile string
}
router.POST("/upload", func(c *gin.Context) {
  file, _ := c.FormFile("file")
  c.String(200, file.Filename)
})

通過curl請求介面,可以看到輕鬆獲取檔名稱。

curl -X POST http://localhost:8080/upload \
  -F "file=@/Users/enoch/Downloads/IMG_9216.JPG" \
  -H "Content-Type: multipart/form-data"
IMG_9216.JPG

當然不止可以拿到檔名,我們還可以使用SaveUploadedFile方法將檔案儲存到某個地方,檔案儲存時要確保有目標目錄的操作許可權。

router.POST("/upload", func(c *gin.Context) {
		file, _ := c.FormFile("file")
		c.String(200, file.Filename)
		err := c.SaveUploadedFile(file, "/Users/enoch/Desktop/ab.png")
		if err != nil {
			c.String(500, err.Error())
		}
})

路由分組

當介面發生重大變更(比如入參出參)時,考慮到向下相容,一般會新增一個介面,但是又希望新介面的名稱顯而易見地看出是老介面的升級版,那麼就可以在介面名前加上版本號v1/article這種形式。

v1 := r.Group("v1")
{
  v1.POST("/login", func(c *gin.Context) {
    c.String(200, "v1/login")
  })
  v1.POST("/submit", func(c *gin.Context) {
    c.String(200, "v1/submit")
  })
}

v2 := r.Group("v2")
{
  v2.POST("/login", func(c *gin.Context) {
    c.String(200, "v2/login")
  })
  v2.POST("/submit", func(c *gin.Context) {
    c.String(200, "v2/submit")
  })
}
curl -X POST http://localhost:8080/v1/login
curl -X POST http://localhost:8080/v2/login

Go語言庫程式碼示例,歡迎star
https://github.com/pingyeaa/golang-examples

感謝大家的觀看,如果覺得文章對你有所幫助,歡迎關注公眾號「平也」,聚焦Go語言與技術原理。

相關推薦

Gin框架系列02路由引數

回顧 上一節我們用Gin框架快速搭建了一個GET請求的介面,今天來學習路由和引數的獲取。 請求動詞 熟悉RESTful的同學應該知道,RESTful是網路應用程式的一種設計風格和開發方式,每一個URI代表一種資源,客戶端通過POST、DELETE、PUT、GET四種請求方式來對資源做增刪改查的操作。 同樣的,

Gin框架系列01極速上手

## Gin是什麼? Gin是Go語言編寫的web框架,具備中介軟體、崩潰處理、JSON驗證、內建渲染等多種功能。 ## 準備工作 本系列演示所有程式碼都在Github中,感興趣的同學可以自行查閱,歡迎大家一起完善。 ```shell https://github.com/pingyeaa/golan

Gin框架系列03換個姿勢理解中介軟體

什麼是中介軟體 中介軟體,英譯middleware,顧名思義,放在中間的物件,那麼放在誰中間呢?本來,客戶端可以直接請求到服務端介面。 現在,中介軟體橫插一腳,它能在請求到達介面之前攔截請求,做一些特殊處理,比如日誌記錄,故障處理等。這就是今天要講述的中介軟體,那麼,它在Gin框架中是怎麼使用的呢?

2Python全棧之路系列之Django路由視圖

request 配置文件 hello 文章 Python全棧之路系列之Django路由與視圖路由說白了就是與視圖(函數)的對應關系,怎麽說呢,一個路由對應一個視圖,比如上面文章中所提到的那樣,當打開/users/路徑的時候會讓users這個函數來進行邏輯處理,把處理的結果再返回到前端。那麽dj

初識vue 2.0(2)路由組件

組件化 script -128 watch css image 暫時 效果 默認 1,在上一篇的創建工程中,使用的的模版 webpack-simple 只是創建了一個簡單的demo,並沒有組件和路由功能,此次采用了webpack模版,自動生成組件和路由。^_^ 在模版初始

security 02 加密解密 、 掃描抓包 、 總結和答疑 、 SELinux安全防護

一段 數字簽名 def 接口 數據流 5.1 調用 message systemctl day01一、selinux安全防護二、數據 加密 解密三、抓包與掃描++++++++++++++++++++++++++++++一、selinux安全防護1.1 selinux 介紹1

三十一、python學習之Flask框架(三)檢視路由、上下文、Flask-Script擴充套件

一、裝飾器路由的具體實現 1.Flask框架路由實現 Flask有兩大核心:Werkzeug和Jinja2 Werkzeug實現路由、除錯和Web伺服器閘道器介面 Jinja2實現了模板。 Werkzeug是一個遵循WSGI協議的python函式庫

SQL注入筆記02基於不同引數型別的注入

數字型 $id=$_GET['x'] Select * from news where id=$id 如:?x=1->Select * from news where id=1 注入更改:無 字

腳手架vue-cli系列安裝規範

我很喜歡Vue的一個重要原因就是因為它的vue-cli,這個工具可以讓一個簡單的命令列工具來幫助我快速地構建一個足以支撐實際專案開發的Vue環境,並不像Angular和React那樣要在Yoman上找適合自己的第三方腳手架。vue-cli的存在將專案環境的初始化工作與複雜度降到了最低。 1.安裝vue-cl

ISTQB AL高階認證系列02ISTQB AL-TA測試分析員學習目標

ISTQB AL-TA(ISTQB高階測試分析員模組)主要是針對測試業務分析人員而設立的知識和實踐。學習完ISTQB AL-TA模組之後,高階測試分析員應能負責完成如下工作: (1)        從

Mongodb從0到1系列 備份恢復

13. 備份與恢復 13.1 備份 Mongodb中使用mongodump命令來備份MongoDB資料,常用語法如下: mongodump -h <hostname><:port> -d <database> -o &

開發一款開源爬蟲框架系列(六)爬蟲分散式化RPC

    最近終於有部分時間繼續開發爬蟲,主要的任務是客戶端和伺服器端分離,這就涉及到遠端呼叫的問題,所以研究了RPC,主要物件是Hessian、JMI、Dubbo、Thrift。進而想用幾篇博文分享一下幾種遠端呼叫協議的一些東西,以後再接著聊爬蟲。有興趣可以訪問我的爬蟲專案:

MFC 錯誤沒有引數列表匹配的 過載函式

CString str; str.Format("Fuck %d",count);//這句話報錯 m_static.SetWindowTextW(str): 錯誤是: 2 IntelliSense:

ISTQB FL初級認證系列02ISTQB FL初級認證考試攻略

ISTQB FL初級認證考試攻略 [概述] ISTQB是國際上唯一的國際權威軟體測試資質認證機構,得到了國際國內眾多軟體測試企業的認可和推崇。本文從幾個方面闡述了ISTQB FL認證需要注意的地方,可

應用程式框架設計(3)RuntimeClass序列化

#define __typeid(Class)    (&Class::x_theRuntimeClass)#define DECLARE_CLASS(Class) const SRuntimeClass *Class::GetRuntimeClass() const;     staticconst

Spring 框架基礎(02)Bean的生命週期,作用域,裝配總結

本文原始碼:GitHub·點這裡 || GitEE·點這裡 一、裝配方式 Bean的概念:Spring框架管理的應用程式中,由

Redis系列(八)釋出訂閱

Redis的釋出與訂閱,有點類似於**訊息佇列**,傳送者往頻道傳送訊息,頻道的訂閱者接收訊息。 ## 1. 釋出與訂閱示例 首先,在本機開啟第1個Redis客戶端,執行如下命令訂閱`blog.redis`頻道: ```shell SUBSCRIBE "blog.redis" ``` ![](http

爬蟲入門到放棄系列02html網頁如何解析

![](https://img-blog.csdnimg.cn/20210201173634123.png) ## 前言 上一篇文章講了爬蟲的概念,本篇文章主要來講述一下如何來解析爬蟲請求的網頁內容。 一個簡單的爬蟲程式主要分為兩個部分,請求部分和解析部分。請求部分基本一行程式碼就可以搞定,所以主要來講述

golangWeb框架---github.com/gin-gonic/gin學習一(路由、多級路由引數傳遞幾種形式)

golangWeb框架---github.com/gin-gonic/gin學習一(路由、多級路由、引數傳遞幾種形式) 2018年09月19日 20:46:01 Saflyer 閱讀數:413更多 所屬專欄: gin/pg(golang)  

Java SSH框架系列使用者登入模組的設計實現思路

1.簡介 使用者登入模組,指的是根據使用者輸入的使用者名稱和密碼,對使用者的身份進行驗證等。如果使用者沒有登入,使用者就無法訪問其他的一些jsp頁面,甚至是action都不能訪問。二、簡單設計及實現 本程式是基於Java的SSH框架進行的。 1.資料庫設計 我們應該設計一個