为什么使用go fiber?
出于好奇心,之前就听闻过这个框架,虽然我的不会Express,听说Fiber是一个参考了Express的Web框架,建立在Go语言写的最快的FasthttpHTTP引擎的基础上。
按官网说的:皆在简化 零内存分配和提高性能,以便快速开发。
至于为啥不用Gin,beego,iris,echo,gf·····感觉上面哪些的框架目前市面上应该是已经很多人,有自己的教脚手架了!我自己出于刚重新接触GO回来没多久的!尝鲜的过程中去学东西也是很有感觉的!所以试一试吧!
目前的它已经出到了V2的版本了,和V1的差别还是比较大的!百度一番之后,也没教程!惯例!哈哈搬砖系列~之官网!!
Fiber 的特点(优势)
官网的大佬的给的几个点:
- 强大的路由
- 静态文件服务
- 极限表现
- 内存占用低
- API 接口
- 中间件和Next支持
- 快速服务器端编程
- 模版引擎
- WebSocket 支持
- 频率限制器
- 15 种语言
Fiber的限制
由于 Fiber 使用了 unsafe 特性,导致其可能与最新的 Go 版本不兼容。Fiber 2.18.0 已经在 Go 1.14 到 1.17 上验证过。
Fiber 与 net/http 接口不兼容。这意味着你无法使用 gqlen,go-swagger 或者任何其他属于 net/http 生态的项目。
Fiber v2.21.0 版本初步使用
本节内容:
- 热更新插件使用
- Fiber app对象的配置项
- Fiber app路由和路由组
- Fiber app启动监听自定义(http和https的配置)
1、来自官网的示例代码
1.1 fresh热重启
插件:
1 | go复制代码D:\code\go\awesomeProject1>go get github.com/pilu/fresh |
使用:
1 | makefile复制代码D:\code\go\awesomeProject1>fresh |
自己玩的示例代码:
1 | go复制代码package main |
启动图示:
然后访问接口即可:http://127.0.0.1:3000/
其实对比Fastapi的框架的来说的,其实框架这东西多数蕾西,而且也和我们的GIN其实总体是保持差不多的。
1.2 其他官网示例的安利
📖 基础路由
1 | go复制代码func main() { |
📖 静态文件服务
1 | bash复制代码func main() { |
📖 中间件和Next
1 | go复制代码func main() { |
📖 根据官网扩展示例-获取路径参数(1)
1 | go复制代码package main |
访问地址:http://127.0.0.1:3000/sdf43534
输出的结果是:
1 | makefile复制代码value: sdf43534 |
📖 根据官网扩展示例-获取路径t数(2)
1 | go复制代码package main |
访问的结果:
1 | csharp复制代码地址:http://127.0.0.1:3000/name |
📖 根据官网扩展示例-获取路径t数(3)-通配符的形式
1 | go复制代码package main |
访问:
1 | markdown复制代码地址:http://127.0.0.1:3000/api/34534/3453 |
📖 【新增】多应用和flask和fastapi的多应用有些类似!
1 | css复制代码func main() { |
上面的访问的的地址则为:GET /john/doe -> 200 OK
2、 Fiber实例的对象的配置
这官网的就有点不地道,锁好翻译很多种语言了!可惜进入官网还是英文!哈哈
那也只好应啃吧!
其实这个的Fiber实例的对象的配置和我们的之前的fastapi的配置是一个概念,就是对我们的Fiber实例的对象进行特殊的参数配置初始化。
2.1 new使用的是默认的配置
1 | css复制代码app := fiber.New() |
2.2 自定义定制个人的配置初始化信息
1 | php复制代码app := fiber.New(fiber.Config{ |
如上面的开启了多进程之后 Prefork: true,:
2.3 配置初始化信息-配置项有哪些?
挑一些比较值得关注的:
- Prefork: 是否开启多进程
+ 默认值是 false
+ 作用: 是否开启多进程模式,官网说注意点是:注意:如果启用了,应用程序将需要在shell中运行,因为预叉模式设置了环境变量。如果您使用的是Docker,请确保该应用程序是与CMD ./app或CMD ["sh", "-c", "/app"]
+ 示例,如果开启多进程的情况后:
如上面的开启了多进程之后 Prefork: true,:

- ServerHeader: 定义响应头中的Server的标记头
- 默认值是 : “”
- 作用:启用Server具有给定值的http标头。
- 示例,写入 ServerHeader: “Fiber”,:
那么我们的请求响应头那就有会:
- CaseSensitive: 路由定义大小写问题的匹配
- 默认值是 : false
- 作用:启用后,/Foo和/foo是不同的路由。
- Immutable :按描述应该是上下文的值是否可复用的问题,以前gin使用的时候也会有这个问题
- 默认值是 : false
- 作用:启用后上下文方法返回的所有值都是不可变的。默认情况下,它们在从处理程序返回之前是有效的
- UnescapePath: 解决的应该是路由中的所有编码字符编码问题
- ETag: 应该解决缓存的问题
- BodyLimit:
- 默认值是:int类型的4 * 1024 * 1024
- 作用:为请求体设置允许的最大大小,如果大小超过配置的限制,它将发送413 - Request Entity Too Large回应
- Concurrency:
+ 默认值是:int类型的256 \* 1024
+ 并发连接的最大数量。
- ReadTimeout:
+ 默认值是:time.Duration
+ 读取请求完成的超时时间显示,默认是不约束。
- WriteTimeout:
+ 默认值是:time.Duration
+ 写入最长响应时间,默认是不约束。
- ReadBufferSize:
请求读取的每个连接缓冲区大小 - DisableKeepalive:
禁用“保持活动连接”,服务器将在向客户端发送第一个响应后关闭传入连接。 - ErrorHandler
- 默认的全局的错误的异常处理。
2.4 应用静态文件服务提供
2.4.1 不设置虚拟路径
配置静态文件:
如设置静态文件的目录:
1 | vbnet复制代码app.Static("/", "./public") |
完整代码:
1 | go复制代码package main |
直接的访问:
1 | arduino复制代码http://127.0.0.1:3000/ |
2.4.2 设置虚拟路径
其中路径实际上不存在于文件系统中,静态方法,为静态目录指定前缀路径
配置静态文件:
如设置静态文件的目录:
1 | vbnet复制代码 app.Static("/static", "./public") |
完整代码:
1 | go复制代码package main |
访问地址:
1 | vbnet复制代码http://127.0.0.1:3000/static/hello.html |
结果:
2.4.3 更多的静态服务配置项参数
1 | php复制代码app.Static("/", "./public", fiber.Static{ |
3、 Fiber路由和路由组
3.1 Fiber路由和路由组
其实这个概念和GIN的类似,如果你接触过GIN的话其实都一样的性质。
完整示例:
1 | go复制代码package main |
具体结果:
3.2 查看所有的路由信息列表
1 | go复制代码package main |
输出的结果为:
4、 Fiber启动的监听
http的启动监听:
通常我们的启动的,可以定制器的HOST和PORT,Fiber也一样的可以提供:
1 | arduino复制代码// 设置启动的监听端口,默认的HOTS的是本地 |
https的启动监听:
1 | arduino复制代码app.ListenTLS(":443", "./cert.pem", "./cert.key"); |
还可以对https进行配置:
1 | yaml复制代码&tls.Config{ |
使用net.Listen来启动
1 | go复制代码package main |
5、 Fiber请求上下文篇
5.1 添加响应头信息
1 | go复制代码package main |
结果:
其他设置响应的方法 c.Set():
1 | go复制代码app.Get("/", func(c *fiber.Ctx) error { |
5.2 返回JSON格式数据
1 | javascript复制代码 return c.JSON(c.App().Stack()) |
完整示例:
1 | go复制代码package main |
或者链式的返回:
1 | javascript复制代码return c.Status(fiber.StatusInternalServerError).JSON(fiber.Map{ |
5.3 获取请求的baseurl和hotsname
1 | less复制代码fmt.Println("c.BaseURL()", c.BaseURL()) |
5.4 获取POST提交的body参数
示例:
1 | go复制代码package main |
结果:
5.5 POST中的body参数绑定解析
示例代码:
1 | go复制代码package main |
结果:
5.6 Cookie设置和删除
1 | go复制代码package main |
5.7 文件下载和发送文件
- 下载文件示例代码:
1 | go复制代码package main |
结果:
- 发送文件示例代码:
从给定路径传输文件。设置内容-类型响应HTTP报头字段
PS:发送文件时候,默认的是开启了gzipping的压缩机制,如果需要关闭,设置为false即可,如下
1 | arduino复制代码c.SendFile("./static/index.html", false); |
演示文件结构:
示例代码:
1 | go复制代码package main |
执行:
5.8 上传文件-获取表单文件内容
番外篇说:
- 1:form-data主要是以键值对的形式来上传参数,同时参数之间以&分隔符分开,同时也可以上传文件,文件上传要指定文件类型。
- 2:x-www-form-urlencode 这种参数的传递与form-data最大的区别是,x-www-form-urlencode只能是以键值对的形式传参,但是不可以上传文件。
按名称检索MultipartForm文件,第一返回来自给定密钥的文件
示例代码:
1 | go复制代码package main |
代码执行结果:
执行上传后:
5.9 多文件接收-获取表单文件内容
示例代码:
1 | css复制代码 |
package main
import (
“fmt”
“github.com/gofiber/fiber/v2”
)
func main() {
app := fiber.New()
app.Post(“/“, func(c *fiber.Ctx) error {
//MultipartForm()。这将返回一个map[string][]string
if form, err := c.MultipartForm(); err == nil {
fmt.Println(“输出表单信息,”, form)
files := form.File[“5gmsg.conf”]
fmt.Println(“输出files信息,”, files)
for _, file := range files {
fmt.Println(file.Filename, file.Size, file.Header[“Content-Type”][0])
if err := c.SaveFile(file, fmt.Sprintf(“./%s”, file.Filename)); err != nil {
return c.SendString(“上传失败!”)
}
}
}
return c.SendString(“上传成功!”)
})
app.Listen(“:3000”)
}
1 |
代码执行结果:
执行上传后:
5.10 获取表单值内容信息
示例代码:
1 | go复制代码package main |
输出结果:
5.11 获取自定义的请求头信息
示例代码:
1 | go复制代码package main |
示例:
5.12 获取客户端请求IP信息
1 | scss复制代码c.IP(), c.IPs() |
示例代码:
1 | go复制代码package main |
执行截图:
5.13 判断Content-Type类型和是否XHR请求
1 | go复制代码package main |
5.14 存贮变量传递(中间件之间的信息传递)
这个其实对后续的鉴权非常有用滴,比如我的鉴权完成后,穿得TOKEN到下一个接口!
示例代码:
1 | go复制代码package main |
执行结果:
5.15 301或302的重定向
示例代码:
1 | go复制代码package main |
访问地址:http://127.0.0.1:3000/coffee
执行结果:
其他示例:
1 | kotlin复制代码app.Get("/", func(c *fiber.Ctx) error { |
5.16 Params参数-获取path参数
代码示例:
1 | go复制代码package main |
访问地址:
1 | arduino复制代码http://127.0.0.1:3000/user/nihao |
执行结果:
复杂匹配示例:
1 | go复制代码package main |
可以访问的地址:
1 | bash复制代码http://127.0.0.1:3000/user2/nihao/3453 |
5.17 获取Query参数和QueryParser参数解析
获取参数示例:
1 | go复制代码package main |
请求返回:
示例绑定解析:
1 | go复制代码package main |
请求执行:
获取是有请求路径和参数信息:
1 | go复制代码package main |
执行结果:
5.18 响应字节流数据
示例代码:
1 | go复制代码package main |
字节流信息的追加写入:
1 | go复制代码 |
执行结果:
5.19 响应码和响应体同时设置
示例代码:
1 | go复制代码package main |
5.20 自定义404的错误响应处理
PS:关键坑点:这个的404自定义的话,你需要放到当所有的路由都注册完成后才可以天机,不然它所有的地址都会找不到!
PS:关键坑点:这个的404自定义的话,你需要放到当所有的路由都注册完成后才可以天机,不然它所有的地址都会找不到!
PS:关键坑点:这个的404自定义的话,你需要放到当所有的路由都注册完成后才可以天机,不然它所有的地址都会找不到!
主要还是使用中间件的方式来处理。
错误的示例代码:
1 | go复制代码package main |
正确的应该是放最后:
1 | go复制代码package main |
执行访问:
6、 Fiber 中间件篇
来自官网的文档的搬砖系列!
6.1 前言:
Fiberv1和Fiberv2的中间件有区别,
Fiberv2中的中间件必须有return c.next()才可以!
其实这个中间件和我们的所知的fastapi和gin的大致的功能是一样的,都是类似的钩子函数一样的。
在FiberV2中它自己内置了很多的中间件:
- 用于基础使用用户名和密码认证的中间件 - BasicAuth
- 缓存作用的中间件 - Cache
- 压缩使用的中间件件 - Compress
- 跨域中间件- CORS
- 过期设置的中间件- ETag
- 设置访问的Favicon图标的中间件
- 配置静态文件服务的一些配置信息中间件-# FileSystem
- 限流中间件 -# Limiter
- 性能分析中间件 -# Pprof
- 日志记录中间件 -# Logger
- 全局异常捕获Recover中间件
- 代理请求访问中间件
- 全局链路追踪RequestID中间件
- Session处理中间件
- 接口请求超时限制的Timeout中间件
下面我的开始搬砖了!!!我就挑几个聊聊!一一的实践一下看看具体的中间件玩法!
6.2 BasicAuth用户名密码基础认证中间件
首先BasicAuth其实就是请求的时候,你需要提供用户名和账号,来验证!
示例代码:
1 | go复制代码package main |
浏览器访问吧!这样明细:然后访问地址:
此时需要你提供用户名和密码:
1 | go复制代码package main |
输入用户名和密码:
6.3 跨域中间件
- 跨域默认配置
1 | yaml复制代码var ConfigDefault = Config{ |
- 跨域中间件使用
1 | go复制代码package main |
6.4 限流中间件
- 限流中间件件默认配置
1 | go复制代码var ConfigDefault = Config{ |
- 限流中间件使用:
示例:5秒内最多给2个访问!
1 | go复制代码package main |
超过的时候:
正常的时候:
6.5 日志中间件
官网文档中提示提供的很多的参数:
甚至它还已经包括了响应体了内容了!!!不需要我fastapi那样还需要自己去写一次了!!!好像可以哟!哈哈
如,日志中可以记录的常量信息如下:
1 | ini复制代码// Logger variables |
默认的日志中间件的配置:
1 | kotlin复制代码var ConfigDefault = Config{ |
- Next:是处理是否传递到下一个的,可以自定义
- Format:定义日志记录的格式
- TimeFormat:日志的记录的时间格式
- TimeZone:日志记录的时间时区
- TimeInterval:时间即那个
- Output:输出到哪里,默认的是控制台
默认的日志配置
1 | less复制代码app.Use(logger.New()) |
然后请求接口控制台会输出日志信息:
添加全局追踪ID日志配置
1 | go复制代码package main |
上面的示例,执行后,我完全没看到有requestid
所以继续往下试一试下入文件看看:
1 | go复制代码package main |
查看我们的日志文件/req.log:
1 | bash复制代码15784 9e7bd80c-4198-4d3e-800a-7fef42810a55 200 - GET /ok1 |
嗯嗯,算是看了!!!!
6.6 全局异常中间件
- 默认的配置信息:
1 | yaml复制代码var ConfigDefault = Config{ |
示例:
1 | go复制代码package main |
执行结果:
这里有疑问,我想捕获我自己定义现实怎么显示呢?
一个自定义的示例:
1 | go复制代码package main |
好像还是有点迷糊?如果全局的处理错误呐?
会看我们的fiber.New配置项中其实有一个ErrorHandler,我们只需要在这个地方定义我们的自己的处理器就可以了!!!
自定义全局异常处理函数:
1 | go复制代码package main |
然后访问验证:
6.7 全局异常中间件-提取出全局错误处理问题
1 | css复制代码app := fiber.New(fiber.Config{ |
3.总结
以上仅仅是个人结合官网做的一系列的实践总结梳理,如有笔误!欢迎批评指正!感谢各位大佬!
码字不易,要不你点个赞呗 哈哈!
结尾
END
简书:www.jianshu.com/u/d6960089b…
公众号:微信搜【小儿来一壶枸杞酒泡茶】
小钟同学 | 文 【欢迎一起学习交流】| QQ:308711822
本文转载自: 掘金