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.ResponseWriter
和 io.Writer
。
Iris提出了一些默认的解析器不支持的通用规则和功能。例如,我们已经支持 yield
,render
,render_r
,current
,urlpath
模板函数, 并通过中间件和嵌入式模板文件为所有的引擎布局和绑定。
为了使用一个模板引擎独特的功能,你需要通过阅读文档来学习模板引擎的特征和语法(点击下面)。选择最适合你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)
}