使用Go语言打造轻量级Web框架

这篇具有很好参考价值的文章主要介绍了使用Go语言打造轻量级Web框架。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

Web框架是Web开发中不可或缺的组件。它们的主要目标是抽象出HTTP请求和响应的细节,使开发人员可以更专注于业务逻辑的实现。在本篇文章中,我们将使用Go语言实现一个简单的Web框架,类似于Gin框架。

功能

我们的Web框架需要实现以下功能:

  • 路由:处理HTTP请求的路由,并支持路径参数和通配符。
  • 上下文:封装HTTP请求和响应,并提供访问请求参数的方法。
  • 中间件:在请求处理之前或之后运行的函数。
  • HTTP请求和响应:支持GET、POST等HTTP方法。
实现

首先,我们需要定义一个HandlerFunc类型,表示处理HTTP请求的函数。这个函数需要接受一个Context类型的参数,用于访问请求和响应。

type HandlerFunc func(Context)

接下来,我们需要定义一个Context类型,封装HTTP请求和响应,并提供访问请求参数的方法。我们可以使用Go语言标准库中的http.ResponseWriterhttp.Request类型分别表示响应和请求。

type Context struct {
Response http.ResponseWriter
Request  *http.Request
Params   map[string]string
}

Params字段用于存储路径参数。例如,如果路由路径为/users/:id,则可以使用c.Params["id"]访问路径参数id的值。

现在,我们可以开始实现路由。我们需要定义一个Route类型,表示一个路由,包含HTTP方法、路径和处理函数。我们还需要一个Router类型,表示整个应用程序的路由器。它应该包含所有的路由,包含需要的中间件,并能够处理HTTP请求。

type Route struct {
    method  string
    path    string
    handler HandlerFunc
}

type Router struct {
    routes []*Route
	middlewares []MiddlewareFunc

}

我们可以使用Handle方法将路由添加到路由器中。

func (r *Router) Handle(method, path string, handler HandlerFunc) {
    r.routes = append(r.routes, &Route{method, path, handler})
}

当HTTP请求到达时,需要遍历所有的路由,并找到匹配的路由。如果找到了一个匹配的路由,我们就调用它的处理函数,并且如果有中间件,需要遍历所有中间件执行中间件处理逻辑。否则,我们返回HTTP 404错误。

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
    var match *Route
    params := make(map[string]string)

    for _, route := range r.routes {
        if req.Method == route.method {
            if ok, p := matchPath(route.path, req.URL.Path); ok {
                match = route
                params = p
                break
            }
        }
    }

    if match != nil {
        handler := match.handler

        for i := len(r.middlewares) - 1; i >= 0; i-- {
            handler = r.middlewares[i](handler)
        }
        handler(Context{w, req, params})
	} else {
        http.NotFound(w, req)
    }
}

在上面的代码中,我们使用了matchPath函数来比较HTTP请求的路径和路由的路径,以确定是否匹配。这个函数还会返回路径参数的值,以便我们可以在Context中访问它们。

现在,我们可以实现中间件。中间件是在请求处理前或处理后运行的函数,它们可以修改请求或响应,或执行其他任务。我们可以定义一个MiddlewareFunc类型,表示中间件函数。

type MiddlewareFunc func(handler HandlerFunc) HandlerFunc

接下来,我们可以在Router中添加一个Use方法,用于注册中间件。这个方法会往路由中添加一个中间件,后面处理函数时候会要遍历使用。

func (r *Router) Use(middleware MiddlewareFunc) {
    r.middlewares = append(r.middlewares, middleware)
}

最后,我们需要添加HTTP方法的支持。我们可以为每个HTTP方法定义一个快捷方法,它们分别调用Handle方法并传递正确的HTTP方法和路径。

例如,对于GET方法,我们可以定义一个GET方法,如下所示:

func (r *Router) GET(path string, handler HandlerFunc) {
    r.Handle("GET", path, handler)
}

现在,我们已经完成了一个简单的Web框架的实现。下面是完整的代码:

完整的代码
package main

import (
	"fmt"
	"net/http"
	"strings"
	"time"
)

type HandlerFunc func(Context)

type Context struct {
	Response http.ResponseWriter
	Request  *http.Request
	Params   map[string]string
}

type Route struct {
	method  string
	path    string
	handler HandlerFunc
}

type Router struct {
	routes      []*Route
	middlewares []MiddlewareFunc
}

type MiddlewareFunc func(handler HandlerFunc) HandlerFunc

func NewRouter() *Router {
	return &Router{}
}

func (r *Router) Handle(method, path string, handler HandlerFunc) {
	r.routes = append(r.routes, &Route{method, path, handler})
}

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	var match *Route
	params := make(map[string]string)

	for _, route := range r.routes {
		if req.Method == route.method {
			if ok, p := matchPath(route.path, req.URL.Path); ok {
				match = route
				params = p
				break
			}
		}
	}

	if match != nil {
		handler := match.handler

		for i := len(r.middlewares) - 1; i >= 0; i-- {
			handler = r.middlewares[i](handler)
		}
		handler(Context{w, req, params})
	} else {
		http.NotFound(w, req)
	}
}

func (r *Router) Use(middleware MiddlewareFunc) {
	r.middlewares = append(r.middlewares, middleware)
}

func (r *Router) GET(path string, handler HandlerFunc) {
	r.Handle("GET", path, handler)
}

func (r *Router) POST(path string, handler HandlerFunc) {
	r.Handle("POST", path, handler)
}

func (r *Router) PUT(path string, handler HandlerFunc) {
	r.Handle("PUT", path, handler)
}

func (r *Router) DELETE(path string, handler HandlerFunc) {
	r.Handle("DELETE", path, handler)
}

func matchPath(path, pattern string) (bool, map[string]string) {
	parts1 := strings.Split(path, "/")
	parts2 := strings.Split(pattern, "/")

	if len(parts1) != len(parts2) {
		return false, nil
	}

	params := make(map[string]string)

	for i, part := range parts1 {
		if part != parts2[i] {
			if strings.HasPrefix(part, ":") {
				params[part[1:]] = parts2[i]
			} else if strings.HasPrefix(part, "*") {
				params[part[1:]] = strings.Join(parts2[i:], "/")
				break
			} else {
				return false, nil
			}
		}
	}

	return true, params
}


使用案例
func main() {

	router := NewRouter()

	router.Use(func(handler HandlerFunc) HandlerFunc {
		return func(ctx Context) {
			start := time.Now()
			handler(ctx)
			fmt.Printf("%s cost %s\n", ctx.Request.RequestURI, time.Now().Sub(start))
		}
	})

	router.GET("/", func(c Context) {
		fmt.Fprintf(c.Response, "欢迎使用我的web框架!")
	})

	router.GET("/users/:id", func(c Context) {
		fmt.Fprintf(c.Response, "User ID: %s", c.Params["id"])
	})

	router.GET("/users/:id/friends", func(c Context) {
		fmt.Fprintf(c.Response, "User ID: %s, list all friends.", c.Params["id"])
	})

	router.GET("/*path", func(c Context) {
		fmt.Fprintf(c.Response, "User path: %s", c.Params["path"])
	})

	http.ListenAndServe(":8080", router)
}

在上面的代码中,我们添加了一个中间件函数记录请求耗时,它用于记录每个HTTP请求的执行。我们还添加了几个路由,以演示路径参数和通配符的用法。

运行结果
$ curl localhost:8080/users
User path: users

$ curl localhost:8080/users/1001
User ID: 1001

$ curl localhost:8080/users/1001/friends
User ID: 1001, list all friends.

$ curl localhost:8080/users/1001/friends/xxx
404 page not found

$ curl localhost:8080/xxxx 
User path: xxxx

---------------------------------------------------
/users cost 51.917µs
/users/1001 cost 2.75µs
/users/1001/friends cost 5.833µs
/xxxx cost 6.875µs
总结

在本文中,我们使用Go语言实现了一个简单的Web框架。我们实现了路由、上下文、中间件、HTTP请求和响应等功能。还演示了如何使用路径参数和通配符来匹配不同的路径。这个Web框架虽然比不上流行的框架,但它可以作为学习Web框架实现的好起点。


欢迎关注,学习不迷路文章来源地址https://www.toymoban.com/news/detail-401377.html

到了这里,关于使用Go语言打造轻量级Web框架的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 用go设计开发一个自己的轻量级登录库/框架吧(拓展篇)

    主库:weloe/token-go: a light login library. 扩展库:weloe/token-go-extensions (github.com) 本篇给主库扩展一个Adapter提供简单的外部数据存储。 一个库/框架往往不能完成所有事情,需要其他库/框架的支持才能达到更加完善的效果。本篇会对token-go框架的Adapter进行简单的拓展。 首先我们应

    2024年02月05日
    浏览(70)
  • 初识Flask:Python轻量级Web框架入门教程

    Flask是一个用Python编写的轻量级Web应用框架。由于其“微”性质,Flask在提供核心服务的同时,仍然提供了许多扩展的可能性。在这篇文章中,我们将从最基础开始,学习如何使用Flask构建一个Web应用。 首先,你需要安装Flask库。使用pip进行安装是最简单的方式: 接着,我们来

    2024年02月14日
    浏览(105)
  • 用go设计开发一个自己的轻量级登录库/框架吧(项目维护篇)

    本篇将开始讲讲开发库/框架的最开始阶段,也就是搭建一个项目 源码:weloe/token-go: a light login library (github.com) 项目结构,不是上一篇所说的代码架构,而是分包,明确的分包更有助于我们的开发。本框架分包如下 我们选择使用GitHub进行代码托管,同时也使用GitHub Actions进行

    2024年02月03日
    浏览(51)
  • 轻量级web开发框架:Flask本地部署及实现公网访问界面

    本篇文章讲解如何在本地安装Flask,以及如何将其web界面发布到公网上并进行远程访问。 Flask是目前十分流行的web框架,采用Python编程语言来实现相关功能。较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团

    2024年02月05日
    浏览(66)
  • python轻量级web框架flask初探,搭建网站原来这么简单

    ✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN新星创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开

    2024年03月19日
    浏览(125)
  • python Web开发 flask轻量级Web框架实战项目--学生管理系统

     上次发的一篇文章,有很多朋友私信我要后面的部分,那咱们就今天来一起学习一下吧,因为我的数据库这门课选中的课题是学生管理系统,所以今天就以这个课题为例子,从0到1去实现一个管理系统。数据库设计部分我会专门出一个博客的,敬请期待吧~~~ 介如很多朋友问

    2024年02月16日
    浏览(61)
  • 轻量级Web报表工具ActiveReportsJS全新发布v4.0,支持集成更多前端框架!

    ActiveReportsJS 是一款基于 JavaScript 和 HTML5 的轻量级Web报表工具,采用拖拽式设计模式,不需任何服务器和组件支持,即可在 Mac、Linux 和 Windows 操作系统中,设计多种类型的报表。ActiveReportsJS 同时提供跨平台报表设计、纯前端报表展示、多数据源绑定、前端打印导出等功能,

    2024年02月15日
    浏览(53)
  • 轻量级web开发框架Flask本地部署及无公网ip远程访问界面

    本篇文章讲解如何在本地安装Flask,以及如何将其web界面发布到公网上并进行远程访问。 Flask是目前十分流行的web框架,采用Python编程语言来实现相关功能。较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团

    2024年02月04日
    浏览(66)
  • 本地部署轻量级web开发框架Flask并实现无公网ip远程访问开发界面

    本篇文章主要讲解如何在本地安装Flask,以及如何将其web界面发布到公网进行远程访问。 Flask是目前十分流行的web框架,采用Python编程语言来实现相关功能。较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团

    2024年01月23日
    浏览(61)
  • Mainflux IoT:Go语言轻量级开源物联网平台,支持HTTP、MQTT、WebSocket、CoAP协议

    Mainflux是一个由法国的创业公司开发并维护的 安全、可扩展 的开源物联网平台,使用 Go语言开发、采用微服务的框架。Mainflux支持多种接入设备,包括设备、用户、APP;支持多种协议,包括HTTP、MQTT、WebSocket、CoAP,并支持他们之间的协议互转。 Mainflux的南向接口连接设备,北

    2024年02月01日
    浏览(115)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包