Iris框架学习

Iris框架介绍

学习网址

Iris官网:https://www.iris-go.com/

Iris github地址:https://github.com/kataras/iris

Iris官方学习文档(英文):https://docs.iris-go.com/iris/

Iris中文文档1:https://learnku.com/docs/iris-go/10/why/3759

Iris中文文档2:https://www.topgoer.com/Iris/

Iris框架的特点

  • Iris是一款通过go语言编写的快速、简单、功能齐全、效率高、免费、开源的Web框架
  • Iris支持MVC架构模式
  • Iris可以被用来作为gRPC的web端口,为gRPC提供API
  • Iris官网中被称作速度最快的Go后端开发框架

Iris入门

安装

安装的唯一要求是Go编程语言,版本在1.15及以上

安装Iris

go get github.com/kataras/iris/v12@master

确保gomod文件中正常导入如下包

require (
	github.com/BurntSushi/toml v1.2.1 // indirect
	github.com/CloudyKit/fastprinter v0.0.0-20200109182630-33d98a066a53 // indirect
	github.com/CloudyKit/jet/v3 v3.0.0 // indirect
	github.com/CloudyKit/jet/v6 v6.1.0 // indirect
	github.com/Joker/jade v1.1.3 // indirect
	github.com/Shopify/goreferrer v0.0.0-20220729165902-8cddb4f5de06 // indirect
	github.com/andybalholm/brotli v1.0.4 // indirect
	github.com/aymerick/douceur v0.2.0 // indirect
	github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible // indirect
	github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385 // indirect
	github.com/fatih/structs v1.1.0 // indirect
	github.com/flosch/pongo2/v4 v4.0.2 // indirect
	github.com/golang/snappy v0.0.4 // indirect
	github.com/google/uuid v1.3.0 // indirect
	github.com/gorilla/css v1.0.0 // indirect
	github.com/iris-contrib/blackfriday v2.0.0+incompatible // indirect
	github.com/iris-contrib/jade v1.1.3 // indirect
	github.com/iris-contrib/pongo2 v0.0.1 // indirect
	github.com/iris-contrib/schema v0.0.6 // indirect
	github.com/josharian/intern v1.0.0 // indirect
	github.com/json-iterator/go v1.1.12 // indirect
	github.com/kataras/blocks v0.0.7 // indirect
	github.com/kataras/golog v0.1.8 // indirect
	github.com/kataras/iris/v12 v12.2.0-beta6.0.20221125222511-29c29e79e5da // indirect
	github.com/kataras/pio v0.0.11 // indirect
	github.com/kataras/sitemap v0.0.6 // indirect
	github.com/kataras/tunnel v0.0.4 // indirect
	github.com/klauspost/compress v1.15.12 // indirect
	github.com/mailgun/raymond/v2 v2.0.48 // indirect
	github.com/mailru/easyjson v0.7.7 // indirect
	github.com/microcosm-cc/bluemonday v1.0.21 // indirect
	github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421 // indirect
	github.com/modern-go/reflect2 v1.0.2 // indirect
	github.com/russross/blackfriday/v2 v2.1.0 // indirect
	github.com/ryanuber/columnize v2.1.0+incompatible // indirect
	github.com/schollz/closestmatch v2.1.0+incompatible // indirect
	github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
	github.com/sirupsen/logrus v1.8.1 // indirect
	github.com/tdewolff/minify/v2 v2.12.4 // indirect
	github.com/tdewolff/parse/v2 v2.6.4 // indirect
	github.com/valyala/bytebufferpool v1.0.0 // indirect
	github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect
	github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
	github.com/yosssi/ace v0.0.5 // indirect
	golang.org/x/crypto v0.3.0 // indirect
	golang.org/x/net v0.2.0 // indirect
	golang.org/x/sys v0.2.0 // indirect
	golang.org/x/text v0.4.0 // indirect
	golang.org/x/time v0.2.0 // indirect
	google.golang.org/protobuf v1.28.1 // indirect
	gopkg.in/ini.v1 v1.67.0 // indirect
	gopkg.in/yaml.v3 v3.0.1 // indirect
)

如果包导入不成功,查看是否配置了有效的GOPROXY环境变量

在这里插入图片描述

快速使用

新建一个go的文件,输入如下代码

package main

import (
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/context"
)

func main() {
	app := iris.New()

	app.Use(iris.Compression)

	app.Get("/hello", func(ctx iris.Context) {
		ctx.HTML("hello <strong>%s</strong>", "world")
	})

	app.Listen(":8080")
}

运行成功后,在网址中输入http://localhost:8080/hello

如果出现hello world,恭喜您,第一个Iris程序运行成功

代码简单介绍

iris.New()创建并返回一个空的iris *Application实例

app.Use()用于在请求执行前进行某种处理,参数为一个或者多个iris.Handler(处理请求)

app.Done()用于在请求执行后进行某种处理

iris.Compression是一种Iris框架对IO数据进行压缩的函数,用于提高数据的传输效率

app.Get()创建一个get请求,第一个参数为请求路径,第二个可变参数为一个或者多个iris.Handler`

ctx为上下文context

Listen()设置端口

请求处理与响应

处理请求的API

支持所有的 HTTP 方法,开发者也可以在相同路劲的不同的方法注册处理器(比如 /user 的 GET 和 POST)。

第一个参数是 HTTP 方法,第二个参数是请求的路径,第三个可变参数应该包含一个或多个iris.Handler,当客户端请求到特定的资源路径时,这些处理器将会按照注册的顺序依次执行。

app := iris.New()

app.Handle("GET", "/contact", func(ctx iris.Context) {
    ctx.HTML("<h1> Hello from /contact </h1>")
})

同时,Iris框架为我们方便使用,利用restful风格的API封装了所有的HTTP方法,去掉了原始的第一个参数。

app := iris.New()

// Method: "GET"
app.Get("/", handler)

// Method: "POST"
app.Post("/", handler)

// Method: "PUT"
app.Put("/", handler)

// Method: "DELETE"
app.Delete("/", handler)

// Method: "OPTIONS"
app.Options("/", handler)

// Method: "TRACE"
app.Trace("/", handler)

// Method: "CONNECT"
app.Connect("/", handler)

// Method: "HEAD"
app.Head("/", handler)

// Method: "PATCH"
app.Patch("/", handler)

// register the route for all HTTP Methods
app.Any("/", handler)

func handler(ctx iris.Context){
    ctx.Writef("Hello from method: %s and path: %s\n", ctx.Method(), ctx.Path())
}

请求参数的获取

对于GET请求参数的获取

app.Get("/user", func(ctx iris.Context) {
    username := ctx.URLParam("username")
    password := ctx.URLParam("password")
    app.Logger().Info(username + "--" + password)
    ctx.WriteString(username + "--" + password)
})

使用ctx.URLParam()来获取GET请求路径上的参数

访问localhost:8080/user?username=zhangsan&password=123456

对于POST请求参数的获取

app.Post("/user/login", func(ctx iris.Context) {
    username := ctx.PostValue("username")
    password := ctx.PostValue("password")
    app.Logger().Info(username + "--" + password)
    ctx.WriteString(username + "--" + password)
})

使用ctx.PostValue()来获取POST请求的参数

使用postman进行测试

在这里插入图片描述

获取json数据

用户传递的数据为json格式或对象时,使用结构体接收

app.Post("/user/json", func(ctx iris.Context) {
    var user = struct {
        Username string `json:"username"`
        Password string `json:"password"`
    }{}
    err := ctx.ReadJSON(&user)
    if err != nil {
        panic(err)
    }
    app.Logger().Info(user)
    ctx.JSON(iris.Map{"user": user, "code": 200})
})

使用ctx.ReadJSON来获取数据

获取具有Restful风格的请求的参数(key-value格式)

app.Get("/user/{userid:int64}/{username:string}", func(ctx iris.Context) {
    userid := ctx.Params().Get("userid")
    username := ctx.Params().Get("username")
    app.Logger().Info(userid + "--" + username)
    ctx.WriteString(userid + "--" + username)
})

使用ctx.Params().Ger()方法通过key值来获取value

Party路由组

随着项目的越来越大,请求也变得越来越多,管理起来越发困难

根据企业中的规范,我们通常将一类请求使用相同的前缀归为一类,例如有关用户信息的请求是/user/***,有关订单的请求是/order/***

这种情况下,我们使用app.Party()将前缀提取出来,方便后续代码的编写和维护

package main

import (
	"fmt"
	"github.com/kataras/iris/v12"
)

func main() {
	app := iris.New()

	app.Use(iris.Compression)

	user := app.Party("/user", func(ctx iris.Context) {
		fmt.Println("这是user请求路由组")
		ctx.Next()
	})
	user.Get("/add", func(ctx iris.Context) {})
	user.Get("/update", func(ctx iris.Context) {})
	user.Get("/delete", func(ctx iris.Context) {})
	user.Get("/get", func(ctx iris.Context) {})

	order := app.Party("/order", func(ctx iris.Context) {
		fmt.Println("这是order请求路由组")
		ctx.Next()
	})
	order.Get("/add", func(ctx iris.Context) {})
	order.Get("/update", func(ctx iris.Context) {})
	order.Get("/delete", func(ctx iris.Context) {})
	order.Get("/get", func(ctx iris.Context) {})

	app.Listen(":8080")
}

页面处理

Iris 通过它的视图引擎提供了 6 种开箱即用的模板解析器。当然开发者仍然可以使用各种go模板解析器作为 Context.ResponseWriter(), 只要实现了 http.ResponseWriterio.Writer

Iris提出了一些默认的解析器不支持的通用规则和功能。例如,我们已经支持 yieldrenderrender_rcurrenturlpath 模板函数, 并通过中间件和嵌入式模板文件为所有的引擎布局和绑定。

为了使用一个模板引擎独特的功能,你需要通过阅读文档来学习模板引擎的特征和语法(点击下面)。选择最适合你app需要的。

内置的视图引擎:

  • 标准 template/html:iris.HTML(...)
  • django:iris.Django(...)
  • handlebars:iris.Handlebars(...)
  • amber:iris.Amber(...)
  • pug(jade):iris.Pug(...)
  • jet:iris.Jet(...)

一个或者多个视图引擎可以注册到相同的应用中,使用 RegisterView(ViewEngine) 方法注册。

如果需要加载静态资源,使用app.HandleDir()方法注册

./views 目录中加载所有后缀为 .html 的模板,然后使用标准库 html/template 包来解析它们。

使用ctx.ViewData()向前端传递数据

package main

import (
	"fmt"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/context"
	"net/http"
)

func main() {
	app := iris.New()
	app.Use(iris.Compression)

    // 加载资源
	app.RegisterView(iris.HTML("./views", ".html").Reload(true))
	app.HandleDir("static", http.Dir("./static"))

	app.Get("/index", func(ctx iris.Context) {
        ctx.ViewData("msg","hello world")
		ctx.View("index.html")
	})
    
	app.Listen(":8080")
}

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
  	<link rel="stylesheet" href="/static/css/style.css">
  	<script src="/static/js/index.js"></script>
</head>
<body>
    首页
    {{.msg}}
</body>
</html>

错误处理

Iris框架封装的常用状态码

200(请求成功):iris.StatusOK

301(请求成功,但是资源被转移):iris.StatusMovedPermanently

302(临时重定向):iris.StatusFound

404(请求内容不存在):iris.StatusNotFound

500(服务器错误):iris.StatusInternalServerError

使用app.OnErrorCode()根据状态码处理请求

app.OnErrorCode(iris.StatusNotFound, func(c *context.Context) {
    c.View("404.html")
})
app.OnErrorCode(iris.StatusInternalServerError, func(c *context.Context) {
    c.WriteString("500")
})

设置重定向

app.Get("/index", func(context *context.Context) {
    context.StatusCode(iris.StatusFound)
    context.Header("Location", "/login")
})

中间件

当我们谈论 Iris 中的中间件时,我们谈论的是一个 HTTP 请求的生命周期中主处理器代码运行前/后运行的代码。例如,日志中间件可能记录一个传入请求的详情到日志中,然后调用处理器代码,然后再编写有关响应的详细信息到日志中。关于中间件的一件很酷的事情是,这些单元非常灵活且可重复使用。

中间件仅是一个 Handler 格式的函数 func(ctx iris.Context),当前一个中间件调用 ctx.Next() 方法时,此中间件被执行,这可以用作身份验证,即如果请求验证通过,就调用 ctx.Next() 来执行该请求剩下链上的处理器,否则触发一个错误响应。

app.Use()在主处理器运行前处理请求,必须有ctx.Next()

app.Done()在主处理器运行后处理请求,当有多个时必须有ctx.Next()

package main

import (
	"fmt"
	"github.com/kataras/iris/v12"
)

func main() {

	app := iris.New()
	app.Use(iris.Compression, before)

	app.Use(before)
	app.Done(after)

	//app.Get("/index", before, index, after)
	app.Get("/index", index)

	app.Listen(":8080")
}
func index(ctx iris.Context) {
	msg := ctx.Values().Get("msg")
	fmt.Println("index==>", msg)
	ctx.Next()
}
func before(ctx iris.Context) {
	ctx.Values().Set("msg", "index")
	fmt.Println("before")
	ctx.Next()
}
func after(ctx iris.Context) {
	fmt.Println("after")
	ctx.Next()
}

session会话

当你使用一个应用程序,你打开它,做了一些改变,然后关闭它。这就像一个会话。计算机知道你是谁。它知道你什么时候开始这个程序,什么什么时候关闭。但是在互联网上,这是一个问题:web服务器不知道你是谁,也不知道你做什么,因为HTTP不能保持状态。

Session 变量通过存储要在多个页面上使用的用户信息(例如用户名,喜欢的颜色等)来解决此问题。默认情况下,Session 变量会一直存在,直到浏览器关闭。

因此,Session 变量保存有关一个用户的信息,并且可用于一个应用程序中的所有页面。

Tip:如果你想要持久化存储,你可以存储数据到数据库中。

Iris 在 iris/sessions 子包中有自己的会话实现和会话管理。你只需导入这个包就能使用了。

一个会话通过 Session 对象的 Start 函数开始,Session 对象是通过 New 函数创建的,这个函数会返回一个 Sessoin

Session 变量通过 Session.Set 方法设置,通过 Session.Get 方法取回。使用 Session.Delete 删除一个变量。要删除整个会话并使之无效,请使用 Session.Destroy 方法。

session 管理器通过 New 方法创建的。

package main

import (
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/sessions"
)

var (
	cookie  = "sessionid"
	session = sessions.New(sessions.Config{Cookie: cookie})
)

func main() {
	app := iris.New()
	app.Use(iris.Compression)

	app.Get("/index", index5)
	app.Get("/login", login)
	app.Get("/logout", logout)
	app.Get("/destory", func(ctx iris.Context) {
		session.Destroy(ctx)
	})

	app.Listen(":8080")
}
func index5(ctx iris.Context) {
	auth, _ := session.Start(ctx).GetBoolean("auth")
	if !auth {
		ctx.StatusCode(iris.StatusForbidden)
		return
	}
	ctx.WriteString("用户已经登录了")
}
func login(ctx iris.Context) {
	session := session.Start(ctx)
	session.Set("auth", true)
}
func logout(ctx iris.Context) {
	session := session.Start(ctx)
	session.Set("auth", false)
}