近段时间需要实现一个转发 post 请求到指定后端服务的小工具,由于一直想学习 gin 框架,所以就使用这个框架进行尝试,预计会产生几篇文章。本文先研究如何在 gin 框架中实现上传和转发功能。
问题提出
一后台 web 服务,有众多历史版本,本身运行无问题,但后来需求变更,需将不同的历史版本单独运行,并指定不同端口。对外相当于有众多的服务。在请求 post 中带有日期时间,需要根据该日期时间将请求转发到不同的端口的后端服务。注意,post 请求是直接使用文件的形式,对文件名称有特定要求。
思路
nginx可以根据端口来转发,但本文是根据请求的内容转发的,因此需要实现一个转发工具。即先读取外部请求的文件内容,解析得到时间,再根据时间,转发到不同的端口服务中。要解决的问题:
如何做到既解析 post 请求,又要将该请求原封不动地发到后端服务?后端服务返回的数据,如何原封不动地返回请求者?
如何管理后端服务?如果使用额外的脚本,则添加了运维部署的步骤,略有麻烦。故考虑在转发工具中实现。
实现
- 使用工具进行 post 请求,并且指定文件名。可用 postman 或 curl,本文使用后者。
转发函数:
- 利用 ctx.Request.FormFile 得到文件名称、文件内容,此时,可以使用 gin 提供的 SaveUploadedFile 函数保存文件,也可以调用 io.Copy 保存。前者省事。
- 调用再次转发函数。
- 将再次转发函数返回值转换成 json 形式,返回 post 请求工具。
再次转发函数:
- 利用 multipart 包创建文件,将上一步得到的文件拷贝进去。
- 再用 http 库发送请求。注意需要设置格式。
- 最后读取请求的返回值,再返回,注意,内容为字节形式。
代码
主要接口代码
1 |
|
实现代码
1 |
|
为测试方便,文中实现的 gin 框架程序在运行时可指定端口。因此,代码中实现了2个 url 的响应函数。
测试
本文使用 sample.json 文件测试,内容如下:
1 | { |
先运行 84 端口服务(称为 84 服务),此为对外的服务。再运行 85 端口服务(称为 85 服务),此为模拟后端的服务。
启动一终端,执行测试命令:
1 | curl http://127.0.0.1:84/foobar/ -X POST -F "file=@sample.json" |
84 服务打印:
1 | [2021-08-25 23:51:19.424 busy.go:79] Server started at 84 |
85 服务打印:
1 | [GIN-debug] Listening and serving HTTP on :85 |
测试命令返回:
1 | % Total % Received % Xferd Average Speed Time Time Time Current |
也可直接向后端服务请求:
1 | $ curl http://127.0.0.1:85/fee/test_back -X POST -F "file=@sample.json" |
2021.9.17 夜