首页 > 后端开发 > Golang > 正文

我如何在几小时内写出 Express-Go

Patricia Arquette
发布: 2024-10-20 06:14:02
原创
342 人浏览过

How I Wrote Express-Go in Hours

如果您曾经使用过 Express.js 这样的 Web 框架,您就会知道它们是多么方便易用。现在,想象一下 Go 的易用性及其性能和稳健性。好吧,这激励我创建了express-go,这是一个受 Express.js 启发的微框架,最重要的是:我在 19 小时内构建了它!旅程很紧张,但每一秒都值得。让我告诉你这一切是如何发生的。官方存储库链接

这个想法

这一切都始于我的想法:“如果有像 Express.js 这样简单的东西,但又具有 Go 的性能,那就太酷了!”。 Go 已经以极简和高性能而闻名,但在编写 Web 服务器时,我觉得仍然缺少像 Express.js 这样更容易使用的东西。

因此,我没有抱怨,而是决定亲自动手,让事情发生。我决心创建一个微框架,让我能够快速轻松地配置路由、处理 HTTP 请求和响应。

旅程的开始

我从基本结构开始:一个可以侦听 HTTP 请求并根据路由执行不同功能的 Go 应用程序。

第一站:路线

我需要做的第一件事是设置路由。我希望能够以与 Express.js 类似的方式定义路由,在其中指定 URL 和处理该路由的函数。

这就是路线的魔力:

type App struct {
    routes map[string]func(req *req.Request, res *req.Response)
}

func NewApp() *App {
    return &App{
        routes: make(map[string]func(req *req.Request, res *req.Response)),
    }
}

func (a *App) Route(path string, handler func(req *req.Request, res *req.Response)) {
    a.routes[path] = handler
}

func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if handler, exists := a.routes[r.URL.Path]; exists {
        request := req.NewRequest(r)
        response := req.NewResponse(w)
        handler(request, response)
    } else {
        http.NotFound(w, r)
    }
}

func (a *App) Listen(addr string) error {
    return http.ListenAndServe(addr, a)
}
登录后复制
登录后复制

这里的想法很简单:我想要一个路由映射 (map[string]func),其中键是 URL,值是处理请求的函数。

处理者的魔力

我最喜欢 Express.js 的事情之一是路由处理程序非常易于使用。因此,我采用了这样的想法:每个路由只是一个接收两个参数的函数:请求和响应。在 Go 中,这需要更多的工作,因为标准库需要大量的手动工作,所以我编写了一些抽象以使其更容易。

处理请求
Go 中的 HTTP 请求涉及到很多结构和方法,因此我将所有这些封装在一个名为 Request 的结构中,并提供了一些方便的方法来获取查询参数、标头和请求正文。

type Request struct {
    Req  *http.Request
    Body string
}

func NewRequest(req *http.Request) *Request {

    bodyBytes, _ := io.ReadAll(req.Body)
    bodyString := string(bodyBytes)

    return &Request{
        Req:  req,
        Body: bodyString,
    }
}

func (r *Request) QueryParam(key string) string {
    params := r.Req.URL.Query()
    return params.Get(key)
}

func (r *Request) Header(key string) string {
    return r.Req.Header.Get(key)
}

func (r *Request) BodyAsString() string {
    return r.Body
}
登录后复制
登录后复制

现在,我可以执行以下操作,而不是直接处理 http.Request:

app.Route("/greet", func(r *req.Request, w *req.Response) {
    name := r.QueryParam("name")
    if name == "" {
        name = "Guest"
    }
    w.Send("Hello, " + name + "!")
})
登录后复制

这使得事情变得更加干净和更具可读性!

轻松应对

发出请求后,是时候让发送响应变得更容易了。响应还需要一定程度的简单性,以便我可以快速发送文本或 JSON。

type App struct {
    routes map[string]func(req *req.Request, res *req.Response)
}

func NewApp() *App {
    return &App{
        routes: make(map[string]func(req *req.Request, res *req.Response)),
    }
}

func (a *App) Route(path string, handler func(req *req.Request, res *req.Response)) {
    a.routes[path] = handler
}

func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    if handler, exists := a.routes[r.URL.Path]; exists {
        request := req.NewRequest(r)
        response := req.NewResponse(w)
        handler(request, response)
    } else {
        http.NotFound(w, r)
    }
}

func (a *App) Listen(addr string) error {
    return http.ListenAndServe(addr, a)
}
登录后复制
登录后复制

结果

在这 19 个小时的工作结束后,我成功创建了express-go:一个快速且易于使用的微框架,其中配置路由和发送响应就像 Express.js 一样简单,但具有所有功能Go 的力量和性能。

使用示例:

这是一个完整的示例,说明它们如何组合在一起:

type Request struct {
    Req  *http.Request
    Body string
}

func NewRequest(req *http.Request) *Request {

    bodyBytes, _ := io.ReadAll(req.Body)
    bodyString := string(bodyBytes)

    return &Request{
        Req:  req,
        Body: bodyString,
    }
}

func (r *Request) QueryParam(key string) string {
    params := r.Req.URL.Query()
    return params.Get(key)
}

func (r *Request) Header(key string) string {
    return r.Req.Header.Get(key)
}

func (r *Request) BodyAsString() string {
    return r.Body
}
登录后复制
登录后复制

简单、干净、切题。我很自豪地说,我能够在不到一天的时间内构建它,最酷的是它为小型项目提供了足够的灵活性,而没有大型框架的所有复杂性。

最后的反思

在 19 小时内创建 Express Go 是一次有趣且充满挑战的旅程。我专注于解决我在使用 Go 服务器时遇到的实际问题,并尝试使一切尽可能直观。当然,还有更多工作要做,但还有很多可以玩的!

如果您好奇,请查看代码并随时做出贡献。毕竟,当我们可以分享过程时,构建这样的工具会更酷!

现在,请原谅我,我要去喝杯咖啡......19个小时后,我应得的,对吧?

以上是我如何在几小时内写出 Express-Go的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!