自己写go web框架第一天(基础知识)

Go语言内置net/http库,封装HTTP编程的基础接口,启动HTTP特别简单

标准库启动web

创建一个main文件

package main

import (
	"net/http"
)

func main(){

	http.HandleFunc("/",indexHandler)

	http.ListenAndServe("",nil) 
}

func indexHandler(w http.ResponseWriter, r *http.Request){
	w.Write([]byte("hello go web"))
}

运行代码在打开浏览器,查看
在这里插入图片描述
我们只设置了一个路由 “/” ,绑定了indexHandler,匹配路由调用函数。
http.ListenAndServe()函数有两个参数,第一个为监听地址,第二个为Handler,如果为nil那么调用默认Handler,我们也可以自定义handler,启动web服务。

实现自定义Handler

GO语言net/http库中

package http

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

func ListenAndServe(addr string, handler Handler) error 

Handler为一个接口类型,那么新建一个结构体,实现ServeHTTP()方法就创建了一个Handler,试一下吧!

package main

import (
	"net/http"
)

//新建一个结构体
type Engine struct {}

//实现ServeHTTP方法
func(engie *Engine)ServeHTTP(w http.ResponseWriter, r *http.Request){
	switch r.URL.Path {
	case "/":
		w.Write([]byte("hello go web"))
	case "/red":
		w.Write([]byte("hello b ge"))
	}
}

func main(){
	//创建结构体实例
	engine := &Engine{}
	//启动服务
	http.ListenAndServe("",engine)
}

浏览器验证:
在这里插入图片描述
我们定义了一个空的结构体Engine,实现了ServeHTTP方法,这个方法有2个参数,第二个参数是 Request ,该对象包含了该HTTP请求的所有的信息,比如请求地址、Header和Body等信息;第一个参数是 ResponseWriter ,利用 ResponseWriter 可以构造针对该请求的响应。
在 main 函数中,我们给 ListenAndServe 方法的第二个参数传入了刚才创建的engine实例。至此,我们走出了实现Web框架的第一步,即,将所有的HTTP请求转向了我们自己的处理逻辑,代码的运行结果与之前的是一致的。

框架雏形

目录说明

.
└── go-user
    ├── README.md
    ├── go.mod
    ├── go.sum
    ├── main.go
    └── red
        └── red.go

go.mod

module go-user

go 1.14

main.go

package main

import (
	"go-user/red"
	"net/http"
)

func main()  {
	r := red.New()

	r.GET("/red", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("hello b ge"))
	})

	r.Run(":8080")
}

端口地址定义为“8080”
red.go

package red

import (
	"fmt"
	"net/http"
)
//定义函数为HandlerFunc类型
type HandlerFunc func(http.ResponseWriter, *http.Request)
//定义Engine结构体 
type Engine struct {
	route map[string]HandlerFunc
}
//实现ServeHTTP方法 根据请求的方法及路径来匹配Handler
func (engine *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	key := r.Method + "-" + r.URL.Path
	if handler, ok := engine.route[key]; ok {
		handler(w, r)
	} else {
		fmt.Fprintf(w, "404 NOT FOUND %s ", r.URL.Path)
	}
}
//外部调用框架入口
func New() *Engine {
	return &Engine{make(map[string]HandlerFunc)}
}
//框架新增路由
func (engine *Engine) addRoute(method string, pattern string, handler HandlerFunc) {
	key := method + "-" + pattern
	engine.route[key] = handler
}
//匹配get方法
func (engine *Engine) GET(pattern string, handler HandlerFunc) {
	engine.addRoute("GET", pattern, handler)
}
//匹配post方法
func (engine *Engine) POST(pattern string, handler HandlerFunc) {
	engine.addRoute("POST", pattern, handler)
}
//启动服务
func (engine *Engine) Run(addr string) (err error) {
	return http.ListenAndServe(addr, engine)
}

我们重点介绍一下这部分的实现。
首先定义了类型HandlerFunc,这是提供给框架用户的,用来定义路由映射的处理方法。我们在Engine中,添加了一张路由映射表router,key 由请求方法和静态路由地址构成,例如GET-/、GET-/hello、POST-/hello,这样针对相同的路由,如果请求方法不同,可以映射不同的处理方法(Handler),value 是用户映射的处理方法。
当用户调用(*Engine).GET()方法时,会将路由和处理方法注册到映射表 router 中,(*Engine).Run()方法,是 ListenAndServe 的包装。
Engine实现的 ServeHTTP 方法的作用就是,解析请求的路径,查找路由映射表,如果查到,就执行注册的处理方法。如果查不到,就返回 404 NOT FOUND 。
执行go run main.go,
启动浏览器验证:
在这里插入图片描述
至此,框架原型出来了,慢慢完善!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值