为了账号安全,请及时绑定邮箱和手机立即绑定

我如何在这个Express-Go里, 在19小时里写出来

标签:
Node.js Go

(Note: To better match the style and grammar of the target language, "Express-Go" is kept as is and placed before the action, and the sentence structure is slightly adjusted.)

来看看硅谷的照片吧!硅谷
点击这里查看硅谷的照片。

如果你曾经使用过像 Express.js 这样的 Web 框架,你就会知道它们有多么便利和易用。现在,想象一下在 Go 语言中也能拥有这种便利性,同时还能享受其高性能和坚固性。正是这种想法促使我创造了 express-go,一个由 Express.js 启发的微型框架,并且最棒的是:我只用了 19 个小时就完成了!这段经历非常紧张,但每一秒都值得。让我来告诉你这一切是怎么发生的。官方仓库链接

错误更正:

已经下载的用户请注意,我忘记在go mod中添加仓库了。当时完成单元测试和示例后,太累就上传了,没注意到这点。现在我已经修正了这个问题,你可以正常安装了。

如何安装

在你的命令行中输入以下命令即可:
go get github.com/BrunoCiccarino/GopherLight/router go get github.com/BrunoCiccarino/GopherLight/req

想法

这一切始于我这么想:"拥有一些像 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 { // 创建一个新的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) { // 实现HTTP服务器的处理逻辑
        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 { // 开始监听指定地址上的HTTP请求
        return http.ListenAndServe(addr, a)
    }

全屏显示 退出全屏

这个想法很简单:我想有一个路由映射,键是URL,值是处理请求的函数,它是一个字符串到函数的映射。

处理器的魔法

我喜欢Express.js的一个地方是它的路由处理程序非常易用。因此,每个路由都被视为一个函数,接收请求和响应两个参数。相比之下,在Go中,这需要更多手动操作,因为标准库缺乏方便的功能,所以我写了一些抽象来简化这个过程。

关于如何处理请求
在 Go 中处理 HTTP 请求涉及很多结构和方法,我将这些封装到一个名为 Request 的结构体中,并提供了一些方便的方法来获取查询参数、头部信息以及请求体。

    // 定义一个请求结构体
    type Request struct {
        Req  *http.Request
        Body string
    }

    // 创建一个新的Request实例
    func NewRequest(req *http.Request) *Request {

        // 读取请求体并转换为字符串
        bodyBytes, _ := io.ReadAll(req.Body)
        bodyString := string(bodyBytes)

        // 返回新的Request实例
        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("你好," + name + ",很高兴见到你!")
    })
    // 处理/greet请求,根据查询参数name生成问候语.

切换到全屏,退出全屏

这样一来,事情就变得更好读、更干净了!

轻松应对

请求发送完毕之后,是时候简化发送响应的过程了。响应也需要简洁,这样我就能快速发送文本或JSON。

定义一个 `Response` 结构体,它包含一个 `HTTP 响应写入器`。

创建一个新的 `Response` 实例。

(`res` 是一个 `Response` 实例) 发送数据。

(`res` 是一个 `Response` 实例) 设置状态码。

(`res` 是一个 `Response` 实例) 将数据编码为 JSON 并发送。

全屏 退出全屏

结果是

在这些19小时的工作后,我成功地开发出了express-go:它是一个快速又易于使用的微框架,配置路由和发送响应与使用Express.js一样简单,但具备Go的强大功能和性能。

用法示例:

这里有一个完整的例子来展示这一切是如何拼凑起来的。

package main

import (
    "github.com/BrunoCiccarino/GopherLight/router"
    "github.com/BrunoCiccarino/GopherLight/req"
    "fmt"
)

func main() {
    app := router.NewApp()

    app.Route("/hello", func(r *req.Request, w *req.Response) {
        w.Send("Hello, World!")
    })

    app.Route("/json", func(r *req.Request, w *req.Response) {
        w.JSON(map[string]string{"message": "Hello, JSON"})
    })

    fmt.Println("Server listening on port 3333")
    app.Listen(":3333")
}

切换到全屏 退出全屏

简单,干净,直截了当。我很自豪,能在一天之内搞定它,而且它有足够的灵活性来应对小项目,而没有大型框架的复杂度。

最后的思考

在19小时之内创建express-go是一段既有趣又具挑战性的经历。我专注于解决在Go服务器上遇到的实际难题,并尽量使一切直观。当然,还有很多好玩的功能和工具可以试一试,但还有更多的工作要做!

如果你对这个感兴趣,可以看看代码,也欢迎贡献。毕竟,这样做,像这样的工具建设过程分享出来会更酷!

现在,如果你们允许,我要去拿杯咖啡,……连续工作了19小时之后,我应该享受一下,对不对?

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消