彩虹女神躍長空,Go語言進階之Go語言高性能Web框架Iris項目實戰-項目入口與路由EP01

書接上回,我們已經安裝好Iris框架,並且構建好了Iris項目,同時配置了fresh自動監控項目的實時編譯,萬事俱備,只欠東風,彩虹女神蓄勢待發。現在我們來看看Iris的基礎功能,如何編寫項目入口文件以及配置路由系統。

項目入口

事實上,Iris遵循的是單一入口模式,說白了就是單一入口文件main.go處理項目所有的來源請求,如此,項目就避免了因為多個文件處理不同的請求而增加的安全性風險,同時也更便於項目的統籌管理。在上一篇文章:急如閃電快如風,彩虹女神躍長空,Go語言進階之Go語言高性能Web框架Iris項目實戰-初始化項目EP00中,我們已經編寫好了入口文件main.go:

package main  
  
import "github.com/kataras/iris/v12"  
  
func main() {  
  app := iris.New()  
  app.Use(iris.Compression)  
  
  app.Get("/", func(ctx iris.Context) {  
    ctx.HTML("你好 <strong>%s</strong>!", "女神")  
  })  
  
  app.Listen(":5000")  
}

這裡解釋一下各行代碼含義,首先聲明包名:

package main

隨後導入Iris包,注意這裡的版本是最新的v12:

import "github.com/kataras/iris/v12"

接着聲明入口(main)函數,並且初始化Iris結構體:

app := iris.New()

隨後加載iris.Compression模塊:

app.Use(iris.Compression)

這裡Compression是Iris內部對IO數據進行壓縮的模塊,可以提高數據傳輸速度。

接着編寫路由註冊,並使用ctx結構體變量來打印數據:

app.Get("/", func(ctx iris.Context) {  
    ctx.HTML("你好 <strong>%s</strong>!", "女神")  
  })

最後監聽系統的5000端口:

app.Listen(":5000")

在此基礎上,進行進一步的改造:

type Article struct {  
	Title string `json:"標題"`  
}

這裡我們聲明一個叫做Artile(文章)的結構體,該結構體可以理解為博客系統中文章的對象類,結構體內有一個數據類型為字符串的字段(屬性)Title(標題),其隱射到Json結果的描述為「標題」。

接着聲明函數:

func list(ctx iris.Context) {  
	article := []Article{  
		{"iris第一章"},  
		{"iris第二章"},  
		{"iris第三章"},  
	}  
  
	ctx.JSON(article)  
  
}

這裡我們聲明一個叫做list的函數,參數為ctx結構體,作用是將文章的標題列表(切片),通過Json的形式返回。

最後將全局註冊的路由,改造為子路由註冊:

articleAPI := app.Party("/")  
	{  
		articleAPI.Use(iris.Compression)  
		articleAPI.Get("/", list)  
  
	}

這裡使用Iris結構體變量內置的Party方法。

完成入口文件代碼:

package main  
  
import "github.com/kataras/iris/v12"  
  
func main() {  
	app := iris.New()  
  
	articleAPI := app.Party("/")  
	{  
		articleAPI.Use(iris.Compression)  
		articleAPI.Get("/", list)  
  
	}  
  
	app.Listen(":5000")  
}  
  
type Article struct {  
	Title string `json:"標題"`  
}  
  
func list(ctx iris.Context) {  
	article := []Article{  
		{"iris第一章"},  
		{"iris第二章"},  
		{"iris第三章"},  
	}  
  
	ctx.JSON(article)  
  
}

修改完畢後,fresh服務會自動幫我們重新編譯項目,然後訪問//localhost:5000

瀏覽器顯示:

[  
{  
標題: "iris第一章"  
},  
{  
標題: "iris第二章"  
},  
{  
標題: "iris第三章"  
}  
]

如此,通過入口文件返回子路由結構體數據的例子就完成了。

路由與請求方式

除了GET請求方式,Iris也支持其他的一些請求方式,一共八種:



app.Get("/someGet", getting)  
app.Post("/somePost", posting)  
app.Put("/somePut", putting)  
app.Delete("/someDelete", deleting)  
app.Patch("/somePatch", patching)  
app.Header("/someHead", head)  
app.Options("/someOptions", options)


這裡只需要將對應的函數進行綁定即可,比如:

func testpost(ctx iris.Context) {  
  
	ctx.WriteString("post請求測試")  
  
}

隨後綁定Post請求:

articleAPI.Post("/", testpost)

接着編寫請求腳本,在項目以外的目錄下建立tests.go文件:

package main  
  
import (  
	"fmt"  
	"io/ioutil"  
	"net/http"  
	"strings"  
)  
  
func main() {  
  
	resp, err := http.Post("//localhost:5000", "application/json;charset=utf-8", strings.NewReader("name=test"))  
	if err != nil {  
		fmt.Println(err)  
		return  
	}  
  
	body, err := ioutil.ReadAll(resp.Body)  
  
	fmt.Println(string(body))  
  
}

這裡通過http包的Post方法來請求//localhost:5000

系統返回:

post請求測試

沒有問題。

路由傳參

在Iris的路由體系中,我們可以直接通過網址進行參數的傳遞:

app.Get("/user/{name}", func(ctx iris.Context) {  
			name := ctx.Params().Get("name")  
			ctx.Writef("Hello %s", name)  
		})

隨後編寫請求腳本:

package main  
  
import (  
	"fmt"  
	"io/ioutil"  
	"net/http"  
)  
  
func main() {  
  
	resp, err := http.Get("//localhost:5000/user/123")  
	if err != nil {  
		fmt.Println(err)  
		return  
	}  
  
	body, err := ioutil.ReadAll(resp.Body)  
  
	fmt.Println(string(body))  
  
}

程序返回:

Hello 123

需要注意的是,這種傳參方式並不會匹配單獨的/user路徑,所以參數不能為空才能匹配到。

如果參數為空,也需要向下匹配,可以採用這種方式:

app.Get("/user/{name}/{action:path}", func(ctx iris.Context) {  
        name := ctx.Params().Get("name")  
        action := ctx.Params().Get("action")  
        message := name + " is " + action  
        ctx.WriteString(message)  
    })

同時也可以聲明參數類型:

app.Post("/user/{name:string}/{action:path}", func(ctx iris.Context) {  
        ctx.GetCurrentRoute().Tmpl().Src == "/user/{name:string}/{action:path}" // true  
    })

Iris內置支持的參數類型:



Param Type	Go Type	Validation	Retrieve Helper  
:string	string	anything (single path segment)	Params().Get  
:uuid	string	uuidv4 or v1 (single path segment)	Params().Get  
:int	int	-9223372036854775808 to 9223372036854775807 (x64) or -2147483648 to 2147483647 (x32), depends on the host arch	Params().GetInt  
:int8	int8	-128 to 127	Params().GetInt8  
:int16	int16	-32768 to 32767	Params().GetInt16  
:int32	int32	-2147483648 to 2147483647	Params().GetInt32  
:int64	int64	-9223372036854775808 to 9223372036854775807	Params().GetInt64  
:uint	uint	0 to 18446744073709551615 (x64) or 0 to 4294967295 (x32), depends on the host arch	Params().GetUint  
:uint8	uint8	0 to 255	Params().GetUint8  
:uint16	uint16	0 to 65535	Params().GetUint16  
:uint32	uint32	0 to 4294967295	Params().GetUint32  
:uint64	uint64	0 to 18446744073709551615	Params().GetUint64  
:bool	bool	"1" or "t" or "T" or "TRUE" or "true" or "True" or "0" or "f" or "F" or "FALSE" or "false" or "False"	Params().GetBool  
:alphabetical	string	lowercase or uppercase letters	Params().Get  
:file	string	lowercase or uppercase letters, numbers, underscore (_), dash (-), point (.) and no spaces or other special characters that are not valid for filenames	Params().Get  
:path	string	anything, can be separated by slashes (path segments) but should be the last part of the route path	Params().Get  



除此以外,Iris也支持傳統的傳參方式:

func main() {  
    app := iris.Default()  
  
    // Query string parameters are parsed using the existing underlying request object.  
    // The request responds to a url matching:  /welcome?firstname=Jane&lastname=Doe  
    app.Get("/welcome", func(ctx iris.Context) {  
        firstname := ctx.URLParamDefault("firstname", "Guest")  
        lastname := ctx.URLParam("lastname") // shortcut for ctx.Request().URL.Query().Get("lastname")  
  
        ctx.Writef("Hello %s %s", firstname, lastname)  
    })  
    app.Listen(":8080")  
}

這裡注意,如果參數為空,可以通過ctx結構體綁定URLParamDefault方法來設置默認值。

結語

通過Iris內置的路由、模型結構體、以及對應的結構體綁定方法,我們已經可以實現普通請求的響應,同時通過多種方式獲取到請求的參數,下一步,將會結合Iris模板來將數據實時渲染至頁面中,欲知後事如何,且聽下回分解。