golang 实现自定义路由器

http 路由实现原理

HTTP 路由组件负责将 HTTP 请求交到对应的函数处理(或者是对应的 struct 的方法),路由在框架中相当于一个事件处理器,而这个事件包括:

  • 用户请求的路径(path),参数
  • HTTP 请求方法(GET|POST|PUT|DELETE|PATCH)

路由器就是根据用户请求的事件信息转发到相应的处理函数(控制层)

ServeMux 路由映射与请求分发原理

默认的路由实现

func fooHandler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
}

http.HandleFunc("/foo", fooHandler)

http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
})

log.Fatal(http.ListenAndServe(":8080", nil))

在以上的例子中,我们可以看到 调用 http 包中的 DefaultServeMux 来添加路由,需要提供两个参数,第一个参数是 URL,第二个参数是访问此 URL 需要执行的函数,以提供用户访问的资源。

路由的思想主要集中在两点:

  • 添加路由的信息

    DefultserveMux.Handle(pattern string, handler Handler)

  • 根据用户请求转发要执行的函数

路由信息的添加:

在 Go 中,默认的路由添加是通过函数 http.Handlehttp.HandleFunc 等来添加,底层都是调用了 DefultserveMux.Handle(pattern string, handler Handler),这个函数会将路由信息存储在一个 map[string]muxEntry 中。

函数处理:

Go 监听端口,然后接收到 tcp 连接后交给 Handler 来处理,通过 http.DefaultServeMux函数来进行调度,遍历之前存储的 map 信息,和用户访问的 URL 进行匹配,查询对应注册的处理函数。

for k, v := range mux.m {
	if !pathMatch(k, path) {
		continue
	}
	if h == nil || len(k) > n {
		n = len(k)
		h = v.h
	}
}

自定义路由器实现

基于以上的理解,我们可以自定义一个路由处理器:

package main

import (
	"fmt"
	"net/http"
)

type MyHandle struct {

}

func (handle *MyHandle) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/hello":
		sayHello(w,r)
		return
	case "/hi":
		sayHi(w,r)
		return
	}
	http.NotFound(w,r)
	return
}

func sayHello(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello Golang!")
}

func sayHi(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hi Golang!")
}

func main() {
	handle := MyHandle{}
	http.ListenAndServe(":9000", &handle)
}

在 终端输入 go run main.go:
打开浏览器:

image-20211116232600815
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值