苦学golang半年,写了一款web服务器

2024-01-06 03:44

本文主要是介绍苦学golang半年,写了一款web服务器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

苦学golang半年,写了一款web服务器

文章目录

  • 苦学golang半年,写了一款web服务器
    • example

项目地址:https://github.com/fengyuan-liang/jet-web-fasthttp

苦学golang半年,写了一款web服务器,里面包含笔者各种工程实践,大佬勿喷😊

为什么不使用Gin,而要自己开发一款web服务器呢?其实gin已经非常好了👍,笔者这里主要是想要把自己开发中的工程实践提炼出来,打造出更加顺手的兵器🏹️(现在还只是个玩具🪀,大家看个乐子就行)

那么在使用Gin中有哪些痛点呢?

  • 繁琐的路由表,在Gin中必须写路由表来映射路由,再写对应的func(ctx *gin.Context ),总感觉多写了一次,而且接口一多,看着一望无际的路由表,总感觉划分的不是很优雅,而且不太好找自己想要的接口;并且笔者在写springBoot项目时,非常喜欢用restful插件来找路由,比如输入/v1/xxx/xxx/xxx就能找到对应的路由,但是在gin的路由表不是很好找

  • 每个gin的路由都必须要手动获取参数,然后校验,校验不通过再返回错误(像下面那样),这部分逻辑感觉完全应该复用(完全忍受不了写重复代码😠)。参数就应该交给框架解析,或者说有切面或者hook来统一完成这部分的逻辑

    // gin
    engine.Get("/v1/xxx", xxx)func xxx(ctx *gin.Context) {var (err errorparams xxxx)// Bind your param dataif err = ShouldBindQuery(ctx, &params); err != nil {ctx.AbortWithStatusJSON(http.StatusOK, "traceId", 400, "bad request"))return}// validator your paramif err = validator.New().Struct(&params) ;err != nil {ctx.AbortWithStatusJSON(http.StatusOK, "traceId", 400, "bad request"))return}// do you codectx.JSON(http.StatusOK, "traceId", "ok"))
    }
    // 相比之下,参数Jet会自动帮你注入到你的参数列表里面,并且可以定义Hook统一在参数解析完毕,调用我们自己方法之前处理参数校验的逻辑
    // Jet
    func(YourJetController) GetV1Xxx(ctx jet.Ctx, args *Xxx) (any, error) {// do you codereturn xxx, err
    }
    
  • 接下来不是Gin的缺点,毕竟Gin只是一个基础的web框架,就是笔者更喜欢MVC架构或者DDD模式开发,这里面使用到依赖注入管理生命周期是比较合适的,笔者也不喜欢用类似wire需要生成代码的方式进行依赖注入,所有笔者使用Dig进行依赖注入,反射的方式其实也只影响项目启动的时间,但是go的启动本身就很快了,看不出啥影响

  • 然后就是定义了一些常用的数据结构,例如TrieLinkedHashMap,在golang里面其实提供的数据结构挺少的,但是像LinkedHashMap用的地方其实很多,我们需要O(1)级别的查找和添加,又需要有序的集合顺序

    func TestLinkedHashMap(t *testing.T) {m := maps.NewLinkedHashMap[string, int]()m.Put("one", 1)m.Put("two", 2)m.Put("three", 3)m.ForEach(func(k string, v int) {t.Logf("%s: %d\n", k, v)})
    }$ go test -run TestLinkedHashMap
    one: 1
    two: 2
    three: 3
    PASS
    ok      GoKit/collection/maps   0.166s
    

example

下面是使用的一个例子

func main() {//jet.Register(&DemoController{})xlog.SetOutputLevel(xlog.Ldebug)jet.AddMiddleware(jet.TraceJetMiddleware)jet.Run(":8080")
}// 使用依赖注入的方式注入需要让Jet管理的Controller
func init() {jet.Provide(NewDemoController)
}func NewDemoController() jet.ControllerResult {return jet.NewJetController(&DemoController{})
}type BaseController struct {jet.IJetController
}// 对参数进行校验,如果不通过会返回`reg_err_info`中定义的错误
func (BaseController) PostParamsParseHook(param any) error {if err := utils.Struct(param); err != nil {return errors.New(utils.ProcessErr(param, err))}return nil
}// PostMethodExecuteHook restful 将所有请求以restful方式返回
func (BaseController) PostMethodExecuteHook(param any) (data any, err error) {// restfulreturn utils.ObjToJsonStr(param), nil
}// 上面的两个hook可以直接让controller继承jet.BaseJetController,这样就不用写了type DemoController struct {BaseController
}type Person struct {Name string `json:"name" validate:"required" reg_err_info="不能为空"` // 校验不通过会返回`reg_err_info`的内容Age  int    `json:"age"`
}// 路由 get /v1/usage/{id}/week 已经可以访问了
func (j *DemoController) GetV1Usage0Week(ctx jet.Ctx, args *jet.Args) (any, error) {ctx.Logger().Infof("GetV1Usage0Week %v", *args)return map[string]any{"request_id": ctx.Logger().GenReqId(), "code": 200, data: args}
}
$ curl http://localhost:8080/v1/usage/1/week
{"request_id":"H5OQ4Jg0yBtg","code":200,"message":"success","data":["1"]}

正常情况下会打印日志的全路径,我们在启动时候加上-trimpath就可以只打印项目的path

image.png

image.png

这篇关于苦学golang半年,写了一款web服务器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/575106

相关文章

Golang HashMap实现原理解析

《GolangHashMap实现原理解析》HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持高效的插入、查找和删除操作,:本文主要介绍GolangH... 目录HashMap是一种基于哈希表实现的键值对存储结构,它通过哈希函数将键映射到数组的索引位置,支持

Go语言开发实现查询IP信息的MCP服务器

《Go语言开发实现查询IP信息的MCP服务器》随着MCP的快速普及和广泛应用,MCP服务器也层出不穷,本文将详细介绍如何在Go语言中使用go-mcp库来开发一个查询IP信息的MCP... 目录前言mcp-ip-geo 服务器目录结构说明查询 IP 信息功能实现工具实现工具管理查询单个 IP 信息工具的实现服

springboot上传zip包并解压至服务器nginx目录方式

《springboot上传zip包并解压至服务器nginx目录方式》:本文主要介绍springboot上传zip包并解压至服务器nginx目录方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录springboot上传zip包并解压至服务器nginx目录1.首先需要引入zip相关jar包2.然

将Java项目提交到云服务器的流程步骤

《将Java项目提交到云服务器的流程步骤》所谓将项目提交到云服务器即将你的项目打成一个jar包然后提交到云服务器即可,因此我们需要准备服务器环境为:Linux+JDK+MariDB(MySQL)+Gi... 目录1. 安装 jdk1.1 查看 jdk 版本1.2 下载 jdk2. 安装 mariadb(my

golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法

《golang获取当前时间、时间戳和时间字符串及它们之间的相互转换方法》:本文主要介绍golang获取当前时间、时间戳和时间字符串及它们之间的相互转换,本文通过实例代码给大家介绍的非常详细,感兴趣... 目录1、获取当前时间2、获取当前时间戳3、获取当前时间的字符串格式4、它们之间的相互转化上篇文章给大家介

基于Python打造一个可视化FTP服务器

《基于Python打造一个可视化FTP服务器》在日常办公和团队协作中,文件共享是一个不可或缺的需求,所以本文将使用Python+Tkinter+pyftpdlib开发一款可视化FTP服务器,有需要的小... 目录1. 概述2. 功能介绍3. 如何使用4. 代码解析5. 运行效果6.相关源码7. 总结与展望1

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经

使用Python实现快速搭建本地HTTP服务器

《使用Python实现快速搭建本地HTTP服务器》:本文主要介绍如何使用Python快速搭建本地HTTP服务器,轻松实现一键HTTP文件共享,同时结合二维码技术,让访问更简单,感兴趣的小伙伴可以了... 目录1. 概述2. 快速搭建 HTTP 文件共享服务2.1 核心思路2.2 代码实现2.3 代码解读3.

JSON Web Token在登陆中的使用过程

《JSONWebToken在登陆中的使用过程》:本文主要介绍JSONWebToken在登陆中的使用过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录JWT 介绍微服务架构中的 JWT 使用结合微服务网关的 JWT 验证1. 用户登录,生成 JWT2. 自定义过滤

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加