GTLC全球技术领导力峰会·上海站,首批讲师正式上线! 了解详情
写点什么

gobox 中的 http 请求处理框架

2019 年 11 月 18 日

gobox中的http请求处理框架

今天和大家介绍下我们自主开发的 go 语言轻型框架 gobox,为什么叫 gobox 呢?因为我们设计让每一个单独的模块都作为一个 box,那这些 box 的集合就称为 gobox,再使用 go 的 pkg 管理机制引入到项目中。随着 go 官方推出了 dep 这个包管理工具,我们把 gobox 中的每一个 box 都单独拿出来作为一个项目管理,这就是现在的 gobox;今天这一期,主要来说下使用 gobox 中的 http 请求处理框架。


http 请求处理架构图


重要的对象

System

system 用于实现 go 官方包中的 http.Handler 接口,它的 ServeHTTP 方法中实现了请求处理框架。


Router

定义和实现 MVC 的路由查找过程。


type Router interface {    MapRouteItems(cls ...controller.Controller) // ⾃动将Controller对象中的Action⽅法映射到路由表    DefineRouteItem(pattern string, cl controller.Controller, actionName string) // ⼿动添加路由规则,pattern为正则表达式
FindRoute(path string) *Route // 实现路由查找过程}
复制代码


SimpleRouter

Router 接口的一个实现,自动映射规则为:


1.controller 名称规则为: ([A-Z][A-Za-z0-9_])Controller$,匹配内容转小写即为 controllerName2.action 名称规则为: ^([A-Z][A-Za-z0-9_])Action$,匹配内容转小写后过滤掉 before 和 after 即为 actionName


自动路由查找规则如下:


1.将 request_uri 视为: /controller/action


2.controller 不存在,则默认为 index,可以修改


3.action 不存在,则默认为 index,可以修改


自定义路由查找规则如下:


1.对 request_uri 做正则匹配


2.如果匹配后存在捕获,则捕获内容会作为 action 中除 context 外的参数,依次传入,都是 string 类型


ActionContext 和 Controller

ActionContext

处理每个请求会创建一个对应 Controller 的 ActionContext 对象:


type ActionContext interface {    Request() *http.Request    ResponseWriter() http.ResponseWriter
ResponseBody() []byte SetResponseBody(body []byte)
BeforeAction() AfterAction() Destruct()}
复制代码


Controller

组织 Action:


type Controller interface {    NewActionContext(req *http.Request, respWriter http.ResponseWriter) ActionContext}
复制代码


gracehttp

这是一个支持平滑重启的 httpserver,平滑重启过程如下:



示例代码

最后附上一个最简单的使用示例:


package main
import ( "github.com/goinbox/gohttp/controller" "github.com/goinbox/gohttp/gracehttp" "github.com/goinbox/gohttp/router" "github.com/goinbox/gohttp/system"
"net/http")
func main() { dcl := new(DemoController) r := router.NewSimpleRouter()
r.DefineRouteItem("^/g/([0-9]+)$", dcl, "get") r.MapRouteItems(new(IndexController), dcl)
sys := system.NewSystem(r)
gracehttp.ListenAndServe(":8001", sys)}
type BaseActionContext struct { Req *http.Request RespWriter http.ResponseWriter RespBody []byte}
func (this *BaseActionContext) Request() *http.Request { return this.Req}
func (this *BaseActionContext) ResponseWriter() http.ResponseWriter { return this.RespWriter}
func (this *BaseActionContext) ResponseBody() []byte { return this.RespBody}
func (this *BaseActionContext) SetResponseBody(body []byte) { this.RespBody = body}
func (this *BaseActionContext) BeforeAction() { this.RespBody = append(this.RespBody, []byte(" index before ")...)}
func (this *BaseActionContext) AfterAction() { this.RespBody = append(this.RespBody, []byte(" index after ")...)}
func (this *BaseActionContext) Destruct() { println(" index destruct ")}
type IndexController struct {}
func (this *IndexController) NewActionContext(req *http.Request, respWriter http.R return &BaseActionContext{ Req: req, RespWriter: respWriter, }}
func (this *IndexController) IndexAction(context *BaseActionContext) { context.RespBody = append(context.RespBody, []byte(" index action ")...)}func (this *IndexController) RedirectAction(context *BaseActionContext) { system.Redirect302("https://github.com/goinbox")}
type DemoActionContext struct { *BaseActionContext}
func (this *DemoActionContext) BeforeAction() { this.RespBody = append(this.RespBody, []byte(" demo before ")...)}
func (this *DemoActionContext) AfterAction() { this.RespBody = append(this.RespBody, []byte(" demo after ")...)}
func (this *DemoActionContext) Destruct() { println(" demo destruct ")}
type DemoController struct {}
func (this *DemoController) NewActionContext(req *http.Request, respWriter http.Re return &DemoActionContext{ &BaseActionContext{ Req: req, RespWriter: respWriter, }, }}

func (this *DemoController) DemoAction(context *DemoActionContext) { context.RespBody = append(context.RespBody, []byte(" demo action ")...)}
func (this *DemoController) GetAction(context *DemoActionContext, id string) { context.RespBody = append(context.RespBody, []byte(" get action id = "+id)...)}
复制代码


运⾏这个代码,请求示例及输出如下:


curl http://127.0.0.1:8001/index before index action index after
curl http://127.0.0.1:8001/index/redirect -IHTTP/1.1 302 FoundContent-Type: text/html; charset=utf-8Location: https://github.com/goinboxDate: Fri, 24 Aug 2018 11:57:11 GMTContent-Length: 14
curl http://127.0.0.1:8001/demo/demodemo before demo action demo after
curl http://127.0.0.1:8001/g/123demo before get action id = 123 demo after
复制代码


所有 destruct 输出为:


index destruct index destruct index destruct demo destruct demo destruc
复制代码


欢迎大家使用,使用中有遇到问题随时反馈,我们会尽快响应,谢谢!


本文转载自公众号 360 云计算(ID:hulktalk)。


原文链接:


https://mp.weixin.qq.com/s/WEOW2Sxe1Y_YgnFZ_Af4Og


2019 年 11 月 18 日 11:46156

评论

发布
暂无评论
发现更多内容

优化软件测试成本的7个步骤

程序员一凡

软件测试 自动化测试 测试工程师 黑盒测试 白盒测试

运维工程师小张的日记

XSKY融合存储

图解定时任务线程池

叫练

面试 定时任务 线程池 Timer 线程池工作原理

翻译:《实用的Python编程》02_06_List_comprehension

codists

Python

直击面试!阿里技术官手码12W字面试小册在Github上爆火

程序员小毕

Java 面试 分布式 简历 面试官

安卓软件开发教程!全世界都在问Android开发凉了吗?offer拿到手软

欢喜学安卓

android 程序员 面试、 移动开发·

日记 2021年2月25日(周四)

Changing Lin

2月春节不断更

2021版面试必问178条性能优化建议!(Java+JVM+Redis+MySQL等)

Java架构追梦

Java 架构 面试 性能优化 金三银四跳槽

安卓天气app开发!2021年Android开发者跳槽指南,社招面试心得

欢喜学安卓

android 程序员 面试 移动开发

添加小助理vx:mxzFAFAFA即可!!

比伯

Java 编程 架构 面试 计算机

研发效能的历史和未来

李小腾

研发效能 数据驱动

Redis不止缓存!百度强推“Redis成长笔记”我粉了!

Java成神之路

Java 程序员 架构 面试 编程语言

国产芯片WiFi物联网智能插座—电源功能设计

不脱发的程序猿

28天写作 二月春节不断更 智能插座 WiFi物联网智能插座 电源设计

Serverless 2.0,鸡蛋还是银弹?

Serverless Devs

腾讯云 阿里云 Serverless 运维 前端

吹爆!阿里新产Spring源码高级笔记,原来看懂源码如此简单

Java成神之路

Java 程序员 架构 面试 编程语言

魔改出一个 Encoder | Rust 学习笔记(一)

李大狗

区块链 rust 入门

Git教程--git merge命令

生之欢愉,时间同行

git 程序员 git merge

开工来面试了几十个人,一言难尽

yes的练级攻略

面试

5G 如何在推动工业运行中发挥出至关重要的作用?

一只数据鲸鱼

5G 物联网 数据可视化 工业物联网 3D可视化

GitHub破百万访问的阿里神作:并发实现原理JDK源码笔记

周老师

Java 编程 程序员 架构 面试

话题讨论 | 英语对IT从业人员重要吗?

happlyfox

IT 话题讨论 28天写作 2月春节不断更 话题王者

3分钟学会如何上手supervisor看门狗

happlyfox

Linux centos7 28天写作 2月春节不断更

技术干货 | 中间件技术在百度云原生测试中的应用实践

百度开发者中心

底层技术 #技术干货#

DCache 分布式存储系统|K-K-Row 缓存模块的创建与使用

TARS基金会

MySQL 数据库 nosql 分布式存储 TARS

2021金三银四涨薪季,这些面试题都掌握了嘛?

ios 面试

常见的初级排序算法,这次全搞懂

Silently9527

Java 排序算法

国产芯片WiFi物联网智能插座—项目简介

不脱发的程序猿

物联网 28天写作 二月春节不断更 WiFi物联网插座 智能插座

诊所数字化:连锁型诊所应用远程会诊做分级诊疗

boshi

数字化医疗 七日更 28天写作

简述:一款优秀的缺陷管理系统有哪些功能特点!

优秀

缺陷管理系统

第一篇文章

棉花糖

到底什么是敏捷

Teobler

敏捷 敏捷开发 敏捷精髓 敏捷书籍

DNSPod与开源应用专场

DNSPod与开源应用专场

gobox中的http请求处理框架-InfoQ