继续学习谢大的Go web框架设计

golang web framework 框架系列文章:

HTTP路由

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

  • 用户请求的路径(path)(eg:/user/12, /article/1),当然还有查询信息(eg:?id=12)
  • HTTP的请求方法(method)(GET,POST,PUT,DELETE,PATHC等)

路由的默认实现

Go的http包设计和实现路由,例子来说明

func fooHander(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path))
} http.Handle("/", 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来添加路由,需要提供2个参数,第一个参数是用户访问资源的URL路径,第二个参数是即将要执行的函数。所以路由思路主要就是2点:

    1. 添加路由信息
    1. 更加用户请求转发到执行的函数上

Go默认的路由添加都是通过函数http.Handle和http.HandleFunc 等来添加,底层都是调用了DefaultServeMux.Handle(pattern string, handler Handler),这个函数会把路由信息存储在一个map信息中map[string]muxEntry, 这个就解决了上面说的第一点。

Go监听端口,然后接收到tcp连接会扔给Handler来处理,上面例子用nil参数,及是用 http.DefaultServeMux,通过DefaultServeMux.ServeHTTP函数进行调度,遍历之前存储的map路由信息,和yoghurt访问的URL进行匹配,用来查询对应的注册函数,这就解决了上面所说的第二点。

Go默认路由的缺点

  • 1.不支持参数设定,例如/user/:uid 这种泛型类型匹配
  • 2.无法很友好的支持REST模式,无法限制访问方法,例如上面例子中,用户访问/foo,可以用GET,POST,DELETE,HEAD等方式访问
  • 3.一般网站路由规则太多,编写频繁。这种路由较多的可以进一步简化,通过struct方法简化

路由设计

针对上面Go默认路由的缺点,首先要解决参数支持就要用到正则, 第二和第三个通过一种变通方法,REST的方法对应到struct的方法中,然后路由到struct而不是函数,这样路由时候就可以根据method来执行不同的方法。

存储路由

根据上面说的思路,设计2个数据类型

controllerInfo,保存路径和对于的struct,这里是一个reflect.Type类型

一个ControllerRegistor,这个是一个slice用来保存用户添加的路由信息

type controllerInfo struct {
regex *regexp.Regexp
params map[int]string
controllerType reflect.Type
}
type ControllerRegistor struct {
routers []*controllerInfo
}

初始化ControllerRegistor

func NewControllerRegistor() *ControllerRegistor {
return &ControllerRegistor{routers: make([]*controllerInfo, 0)}
}

ControllerRegistor对外的函数Add,添加url和对于的执行函数

func (p *ControllerRegistro) Add(pattern string, c ControllerInterfce)

在上面的函数中,第二个参数 ControllerInterfce 将在后面一节controller设计中讲解,它是一个interface 类型

还有一个自动路由,实现的是Go定义的函数ServeHTTP

func (p *ControllerRegistor) ServeHTTP(rw http.ResponseWriter, r *http.Request) 

完整代码:

代码地址 router.go

golang web框架设计2:自定义路由的更多相关文章

  1. golang web框架设计7:整合框架

    把前面写好的路由器,控制器,日志,都整合在一起 全局变量和初始化 定义一些框架的全局变量 var ( BeeApp *App AppName string AppPath string StaticD ...

  2. golang web框架设计6:上下文设计

    context,翻译为上下文,为什么要设计这个结构?就是把http的请求和响应,以及参数结合在一起,便于集中处理信息,以后框架的扩展等.好多框架比如gin,都是有这个上下文结构. context结构为 ...

  3. golang web框架设计5:配置设计

    配置信息的解析,实现的是一个key=value,键值对的一个配置文件,类似于ini的配置格式,然后解析这个文件,把解析的数据保存到map中,最后调用的时候通过几个string,int之类的函数返回相应 ...

  4. golang web框架设计4:日志设计

    beego的日志设计思路来自于seelog,根据不同的level来记录日志,beego设计的日志是一个轻量级的,采用系统log.Logger接口,默认输出到os.Stdout,用户可以实现这个接口然后 ...

  5. golang web框架设计3:controller设计

    继续学习golang web框架设计 controller作用 MVC设计模式里面的这个C,控制器. Model是后台返回的数据: View是渲染页面,通常是HTML的模板页面: Controller ...

  6. golang web框架设计1:框架规划

    GO WEB 编程13节,如何设计一个web框架 学习谢大的web框架设计 总体介绍 实现一个简易的web框架,我们采用mvc模式来进行开发. model:模型,代表数据结构.通常来说,模型类时包含查 ...

  7. 在 node.js 的 express web 框架中自动注册路由

    该方法主要是动态注册自己写的 router . 注册器 router 文件名为 loader.js  . var express = require('express'); var fs = requ ...

  8. CI 框架中的自定义路由规则

    在 CI 框架中,一个 URL 和它对应的控制器中的类以及类中的方法是一一对应的,如: www.test.com/user/info/zhaoyingnan 其中 user 对应的就是控制器中的 us ...

  9. golang web框架 kratos中的日志框架

    kratos是bilibili开源的一个web框架. 日志用法: logger.go package kratoslog import ( "flag" "github. ...

随机推荐

  1. 【好好补题,因为没准题目还会再出第三遍!!】ACM字符串-组合数学(官方题解是数位DP来写)

    ACM字符串 .长度不能超过n .字符串中仅包含大写字母 .生成的字符串必须包含字符串“ACM”,ACM字符串要求连在一块! ok,是不是很简单?现在告诉你n的值,你来告诉我这样的字符串有多少个 输入 ...

  2. 今天把自己的ocr镜像开源了

    docker pull docker.io/zhangbo2008/ocr_docker_byzhang:v1 即可,欢迎下载

  3. django2为什么要用序列化

    https://www.jianshu.com/p/1e404604d5c3 结论:如果没用序列化,Django默认将数据进行多次转换才能提取我们所需数据,出现关联时我们还需进一步对数据进行查询,操作 ...

  4. [Google Guava] 11-事件总线

    原文链接 译文连接 译者:沈义扬 传统上,Java的进程内事件分发都是通过发布者和订阅者之间的显式注册实现的.设计EventBus就是为了取代这种显示注册方式,使组件间有了更好的解耦.EventBus ...

  5. [Google Guava] 7-原生类型

    原文链接 译文链接 译者:沈义扬,校对:丁一 概述 Java的原生类型就是指基本类型:byte.short.int.long.float.double.char和boolean. 在从Guava查找原 ...

  6. 总结 1121 Java面向对象

    总结 Java面向对象的基础 三大特征: 封装(抽象),继承,多态 面向对象的内存分析: 栈, 堆, 代码区, 静态区 this: 代表当前对象本身 有时候需要把当前调用对象进行传递,那么就可以使用t ...

  7. tap 事件会触发两次问题

    因项目中使用 coffeeScript (http://coffee-script.org/),此处记录下用 coffeeScript 语法解决 tap 事件触发两次的问题. 在 id="b ...

  8. 浏览器事件环(EventLoop)

    1. 基础知识 1. js语言特点 1. js语言是单线程语言,主线程是单线程.如UI渲染,脚本加载是主线程任务. 2. js语言采用事件循环(EventLoop)机制. 2. 同步任务: 不被引擎挂 ...

  9. 重新梳理一下adb操作app(golang版)

    主要参考我之前整理的内容https://www.cnblogs.com/pu369/p/10490668.html,梳理简化一下思路,以便于用最简单的代码来应对无聊人士的要求. 需求主要是:打开手机. ...

  10. Codevs 2492 上帝造题的七分钟 2(线段树)

    时间限制: 1 s 空间限制: 64000 KB 题目等级 : 大师 Master 题目描述 Description XLk觉得<上帝造题的七分钟>不太过瘾,于是有了第二部. " ...