从零实现Go语言Web框架Gee:第一天理解http.Handler

从零实现Go语言Web框架Gee:第一天理解http.Handler

7days-golang 7 days golang programs from scratch (web framework Gee, distributed cache GeeCache, object relational mapping ORM framework GeeORM, rpc framework GeeRPC etc) 7天用Go动手写/从零实现系列 7days-golang 项目地址: https://gitcode.com/gh_mirrors/7d/7days-golang

前言

在Go语言生态中,Web框架的选择非常丰富,其中Gin以其高性能和简洁的API设计广受欢迎。本文将带大家从零开始实现一个类似Gin的Web框架Gee,第一天我们将聚焦于理解Go标准库中的net/httphttp.Handler接口。

Go标准库的Web服务基础

Go语言内置的net/http库提供了构建Web服务的基础组件。让我们先看一个简单的例子:

package main

import (
	"fmt"
	"log"
	"net/http"
)

func main() {
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
	})
	
	http.HandleFunc("/hello", func(w http.ResponseWriter, r *http.Request) {
		for k, v := range r.Header {
			fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
		}
	})
	
	log.Fatal(http.ListenAndServe(":9999", nil))
}

这个简单的Web服务器做了两件事:

  1. 处理根路径/的请求,返回请求的路径
  2. 处理/hello路径的请求,返回所有的请求头信息

理解http.Handler接口

Go的net/http库的核心是http.Handler接口:

type Handler interface {
    ServeHTTP(ResponseWriter, *Request)
}

任何实现了ServeHTTP方法的类型都可以作为HTTP处理器。这为我们构建Web框架提供了切入点。

自定义处理器实现

我们可以创建一个自定义类型来实现http.Handler接口:

type Engine struct{}

func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	switch r.URL.Path {
	case "/":
		fmt.Fprintf(w, "URL.Path = %q\n", r.URL.Path)
	case "/hello":
		for k, v := range r.Header {
			fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
		}
	default:
		fmt.Fprintf(w, "404 NOT FOUND: %s\n", r.URL)
	}
}

func main() {
	engine := new(Engine)
	log.Fatal(http.ListenAndServe(":9999", engine))
}

这种实现方式让我们可以:

  • 统一处理所有HTTP请求
  • 集中管理路由逻辑
  • 方便添加统一的预处理和后处理逻辑

构建Gee框架雏形

现在,我们将上述概念组织成一个简单的Web框架结构:

// gee/gee.go
package gee

import (
	"fmt"
	"net/http"
)

type HandlerFunc func(http.ResponseWriter, *http.Request)

type Engine struct {
	router map[string]HandlerFunc
}

func New() *Engine {
	return &Engine{router: make(map[string]HandlerFunc)}
}

func (e *Engine) addRoute(method, pattern string, handler HandlerFunc) {
	key := method + "-" + pattern
	e.router[key] = handler
}

func (e *Engine) GET(pattern string, handler HandlerFunc) {
	e.addRoute("GET", pattern, handler)
}

func (e *Engine) POST(pattern string, handler HandlerFunc) {
	e.addRoute("POST", pattern, handler)
}

func (e *Engine) Run(addr string) error {
	return http.ListenAndServe(addr, e)
}

func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	key := r.Method + "-" + r.URL.Path
	if handler, ok := e.router[key]; ok {
		handler(w, r)
	} else {
		fmt.Fprintf(w, "404 NOT FOUND: %s\n", r.URL)
	}
}

使用这个框架的示例:

// main.go
package main

import (
	"fmt"
	"net/http"
	"gee"
)

func main() {
	r := gee.New()
	r.GET("/", func(w http.ResponseWriter, req *http.Request) {
		fmt.Fprintf(w, "URL.Path = %q\n", req.URL.Path)
	})
	
	r.GET("/hello", func(w http.ResponseWriter, req *http.Request) {
		for k, v := range req.Header {
			fmt.Fprintf(w, "Header[%q] = %q\n", k, v)
		}
	})
	
	r.Run(":9999")
}

框架设计解析

  1. HandlerFunc类型:定义了框架使用者的请求处理函数格式
  2. 路由表(router):使用map存储方法-路径到处理函数的映射
  3. 添加路由:通过GET/POST等方法添加路由规则
  4. 服务启动:Run方法包装了http.ListenAndServe
  5. 请求处理:ServeHTTP方法查找并执行对应的处理函数

总结

今天我们实现了Gee框架的最基础版本,核心功能包括:

  • 基于http.Handler接口的框架入口
  • 简单的路由表管理
  • 基本的请求分发机制

虽然功能还很基础,但已经具备了Web框架的雏形。在接下来的开发中,我们将逐步添加动态路由、中间件、模板渲染等更强大的功能。

这个简单的框架实现展示了Go语言标准库的强大之处,通过理解http.Handler接口,我们可以轻松地构建自己的Web框架。对于初学者来说,这也是理解Go Web开发底层原理的绝佳起点。

7days-golang 7 days golang programs from scratch (web framework Gee, distributed cache GeeCache, object relational mapping ORM framework GeeORM, rpc framework GeeRPC etc) 7天用Go动手写/从零实现系列 7days-golang 项目地址: https://gitcode.com/gh_mirrors/7d/7days-golang

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瞿旺晟

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值