Mygin实现简单的路由

本文是Mygin第二篇

目的:

  • 实现路由映射
  • 提供了用户注册静态路由方法(GET、POST方法)

基于上一篇 Mygin 实现简单Http 且参照Gin

  • 我使用了map数组实现简单路由的映射关系
  • 不同的method对应一个组,Gin框架初始化时map时初始化9个,因为支持的http.method刚好为9个
package http
//Gin 中对应的9个方法
const (
	MethodGet     = "GET"
	MethodHead    = "HEAD"
	MethodPost    = "POST"
	MethodPut     = "PUT"
	MethodPatch   = "PATCH" // RFC 5789
	MethodDelete  = "DELETE"
	MethodConnect = "CONNECT"
	MethodOptions = "OPTIONS"
	MethodTrace   = "TRACE"
)

mygin路由功能实现

package mygin

import (
	"log"
	"net/http"
)

type Engine struct {
	trees methodTrees
}

// 路由树
type methodTrees map[string]methodTree

// 路由节点
type methodTree struct {
	method string
	paths  map[string]http.HandlerFunc
}

// 获取路由root根
func (e *Engine) getRoot(method string) methodTree {
	if root, ok := e.trees[method]; ok {
		return root
	}
	e.trees[method] = methodTree{method: method, paths: make(map[string]http.HandlerFunc)}
	return e.trees[method]
}

// 添加路由方法
func (e *Engine) addRoute(method, path string, handler http.HandlerFunc) {
	root := e.getRoot(method)

    //是否已经在路由数上绑定,如果已经绑定就不在继续绑定
	if _, ok := root.paths[path]; ok {
		log.Default().Println(path, "is exist")
		return
	}
    //将path与处理方法关系绑定
	root.method = method
	root.paths[path] = handler

}

func (e *Engine) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    //对应method中的路由树
	if tree, ok := e.trees[r.Method]; ok {
        //路由数中path映射
		if handler, ok := tree.paths[r.URL.Path]; ok {
			handler(w, r)
			return
		}
	}
    //在路由数中没有找到对应的路由
	w.Write([]byte("404 Not found!\n"))
}

// Get Get方法
func (e *Engine) Get(path string, handler http.HandlerFunc) {
	e.addRoute(http.MethodGet, path, handler)
}

// Post  Post方法
func (e *Engine) Post(path string, handler http.HandlerFunc) {
	e.addRoute(http.MethodPost, path, handler)
}

// Default returns an Engine
func Default() *Engine {
	return &Engine{trees: make(methodTrees, 2)}
}

// Run 启动方法start a http server
func (e *Engine) Run(addr string) {
	err := http.ListenAndServe(addr, e)
	if err != nil {
		return
	}
}

main方法调用

package main

import (
	"gophp/mygin"
	"net/http"
)

func main() {
	engine := mygin.Default()
    
	engine.Get("/hello", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte("Mygin Get hello method"))
	})

	engine.Post("/hello", func(writer http.ResponseWriter, request *http.Request) {
		writer.Write([]byte("Mygin Post hello method"))
	})

	engine.Run(":8088")
}

curl请求测试

~ curl 127.0.0.1:8088/hello
Mygin Get hello method#
~ curl -X POST http://127.0.0.1:8088/hello
Mygin Post hello method#
 ~ curl -X POST http://127.0.0.1:8088/hello2
404 Not found!
posted @ 2024-01-16 16:55  Scott_pb  阅读(37)  评论(0编辑  收藏  举报