发布于:,更新于:

01.Mygin实现简单Http

本篇是完全参考gin的功能,自己手动实现一个类似的功能,帮助自己理解和学习gin框架。目的:简单介绍net/http库以及http.Handler接口,实现简单路由请求的功能。

目的

  • 简单介绍net/http库以及http.Handler接口
  • 实现简单路由请求的功能

标准库启动Web服务

先看用标准库怎样启动一个web服务

1
2
3
4
5
6
7
8
9
import "net/http"

func helloHandler(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("hello world"))
}
func main() {
http.HandleFunc("/hello", helloHandler)
http.ListenAndServe(":8088", nil)
}
设置路由

我设置了一个 /hello 的简单路由,GET请求后返回 hello world。

1
2
 ~ curl 127.0.0.1:8088/hello
hello world

为什么请求路由能够返回hello world,这就要从Golang的http包ListenAndServe.go中查看了。

ListenAndServe源码查看

我已经将源码上的注释翻译成了中文

1
2
3
4
5
6
7
8
9
10
11
// ListenAndServe监听TCP网络地址addr,然后调用
//使用处理程序处理传入连接的请求。
//被接受的连接被配置为使能TCP keepalive。
//
//处理程序通常为nil,在这种情况下使用DefaultServeMux。
//
// ListenAndServe总是返回一个非nil错误。
func ListenAndServe(addr string, handler Handler) error {
server := &Server{Addr: addr, Handler: handler}
return server.ListenAndServe()
}

实现Handler接口

  • http包中HandleFunc的第二个参数是什么意思?点进官方包去看。
    1
    2
    3
    4
    5
    package http

    type Handler interface {
    ServeHTTP(w ResponseWriter, r *Request)
    }
    看到第二个参数是要实现 Handler 接口的方法,根据路由匹配交给实现对应的方法处理。
engine.go编写

基于此改造封装mygin/engine.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package mygin

import (
"net/http"
)

type Engine struct {
}

//ServeHTTP 方法
func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
switch r.URL.Path {
case "/":
w.Write([]byte("success \n"))
case "/hello":
w.Write([]byte("hello world! \n"))
default:
w.Write([]byte("404 NOT FOUND" + r.URL.Path + " \n"))
}
}

func Default() *Engine {
return &Engine{}
}

func (e *Engine) Run(addr string) {
err := http.ListenAndServe(addr, e)
if err != nil {
return
}
}

可以看到我编写了一个engine.go文件,包含了ServeHTTP方法,也就是engine实现了http包中 Handler 接口。http.ListenAndServe第二个参数把engine对象传过去,在http在处理时,就会去调用engine中的ServeHTTP方法。

main.go中调用
1
2
3
4
5
6
7
8
package main

import "gophp/mygin"

func main() {
engine := mygin.Default()
engine.Run(":8088")
}

编写好上诉代码后,启动main方法,可以看到我将 :8088当作地址传入调用engine.go中的Run方法,将 :8088 当作第一个参数传入http.ListenAndServe中,表示监听8088端口,第二个参数则是我们基于net/http标准库实现Web框架的入口,也就是engine中的ServeHTTP方法。

curl请求
1
2
3
4
 ~ curl 127.0.0.1:8088/hello
hello world!
~ curl 127.0.0.1:8088
success

看到上诉结果,代表已经实现了最核心的第一步,在Golang中,不管什么web框架,所有的请求都是在此基础上运行的。赶快去试试吧。




本站由 [PengBin](/) 使用 [Stellar 1.26.3](https://github.com/xaoxuu/hexo-theme-stellar/tree/1.26.3) 主题创建。 本博客所有文章除特别声明外,均采用 [CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by-nc-sa/4.0/) 许可协议,转载请注明出处。