不太一样的Go Web框架—编程范式
项目地址:https://github.com/Codexiaoyi/linweb
这是一个系列文章:
前言
上文说过,linweb不追求性能,相比而言注重编程范式。本人也是dotneter,个人觉得.net那种注解定义路由的方式更为舒服,并且接口文件统一规定在Controller文件夹下,以 XxxController 命名。
当然,在Go中也是可以实现这样的方式,但是将用到大量反射,所以势必会降低性能,所以说"不太一样的Web框架"。
基本范式
所谓编程范式,也就是你的框架定义规范,使用用户按照你的规范写逻辑业务。
路由
路由解析是一个web框架不可避免的模块,我们看gin是如何定义路由的。
func main() {
router := gin.Default()
// Simple group: v1
v1 := router.Group("/v1")
{
v1.POST("/login", loginEndpoint)
v1.POST("/submit", submitEndpoint)
v1.POST("/read", readEndpoint)
}
// Simple group: v2
v2 := router.Group("/v2")
{
v2.POST("/login", loginEndpoint)
v2.POST("/submit", submitEndpoint)
v2.POST("/read", readEndpoint)
}
router.Run(":8080")
}
在应用gin的时候,我们通常会将路由定义与接口方法对应写在一起,统一管理,这样管理方便,也是Go的web框架多数采用的方式。
相比之下,linweb更希望路由定义和方法放在一起,然后以定义Controller的方式,路由地址更加直观。
package controllers
import (
"github.com/Codexiaoyi/linweb/interfaces"
)
type BlogController struct {
}
//[GET("/blog/:id")]
func (blog *BlogController) GetBlog(c interfaces.IContext) {
}
在根目录下创建一个 controllers 文件夹,所有的api都定义在controllers包中。根据不同的 controller 名称区分文件。
自定义插件
linweb中所有功能与主流程间的依赖都是解耦的,所有实现都面向接口,完全遵守依赖倒置原则。
要实现这样的方式也不难:
- 定义一套接口,使得实现相应接口的结构体都可以运行在linweb中。
- 完成默认实现,默认应用默认实现在linweb中。
- 开放传入自定义插件实现的方法。
代码实现
在Go语言框架中大量使用Option模式实现上述的需求(完整代码详见github)。
1.首先我们定义一个自定义插件类型,并写一个默认的插件函数。
//自定义插件类型,返回可以传入Linweb的函数
type CustomizePlugins func(lin *Linweb)
func defaultPlugins() CustomizePlugins {
return func(lin *Linweb) {
lin.markRouter = router.New()
lin.markContext = &context.Context{}
lin.markMiddleware = &middleware.Middleware{}
lin.markInject = injector.Instance()
lin.markCache = cache.Instance()
lin.markModel = &model.Model{}
}
}
2.定义各个插件模块对应的快捷入口函数。
// Customize router plugin.这里参数传入自定义的Router实现
func RouterPlugin(router interfaces.IRouter) CustomizePlugins {
return func(lin *Linweb) {
lin.markRouter = router
}
}
// Customize context plugin.
func ContextPlugin(context interfaces.IContext) CustomizePlugins {
return func(lin *Linweb) {
lin.markContext = context
}
}
......
3.在linweb包的New初始化函数中,传入用户自定义的CustomizePlugins。
// Create a new Linweb.
// Add customize plugins with method of plugins.go, otherwise use default plugins.
func NewLinweb(plugins ...CustomizePlugins) *Linweb {
lin := &Linweb{}
//应用默认插件
defaultPlugins()(lin)
//根据传入的用户自定义插件覆盖默认插件
for _, plugin := range plugins {
plugin(lin)
}
pluginsModel = lin.markModel
Cache = lin.markCache
return lin
}
如何应用
在linweb项目中的linweb_test.go中,用到了mock框架(后续测试部分会介绍)模拟接口实现:
// Arrange:mock data
ctrl := gomock.NewController(t)
defer ctrl.Finish()
// mock a new context instance
mock_context := mocks.NewMockIContext(ctrl)
//Act
linweb := NewLinweb(ContextPlugin(mock_context))
如代码所见,我们调用linweb的ContextPlugin函数传入自定义插件,再将返回值传入NewLinweb初始化函数中。
总结
本文,介绍了linweb的基本的编程范式,也实现了自定义插件功能。
接下来,我们需要根据前文说的功能逐步添加到linweb中。
不太一样的Go Web框架—编程范式的更多相关文章
- 从零构建一个简单的 Python Web框架
为什么你想要自己构建一个 web 框架呢?我想,原因有以下几点: 你有一个新奇的想法,觉得将会取代其他的框架 你想要获得一些名气 你遇到的问题很独特,以至于现有的框架不太合适 你对 web 框架是如何 ...
- Python高级网络编程系列之终极篇---自己实现一个Web框架
通过前面几个小节的学习,现在我们想要把之前学到的知识点给串联起来,实现一个很小型的Web框架.虽然很小,但是用到的知识点都是比较多的.如Socket编程,装饰器传参在实际项目中如何使用.通过这一节的学 ...
- Python编程Web框架 :Django 从入门到精通
Django是一个高级别的Python Web框架,它鼓励快速开发和干净实用的设计. 现在我们开始学习它. Django学习之 第一章:Django介绍 Django学习之 第二章:Django快速上 ...
- 两个Python web框架:Django & Tornado比较
就是说它作为 web 框架比 Django 简单,又支援异步 IO,且更不需要前端的 webserver ? 我已经混乱了, Tornado是 Nginx.Django.Node.js 的结合体?又或 ...
- 蜗牛历险记(二) Web框架(中)
上篇简单介绍了框架所使用的Autofac,采用Autofac提供的Ioc管理整个Web项目中所有对象的生命周期,实现框架面向接口编程.接下来介绍框架的日志系统. 一.介绍之前 框架日志是否有存在的必要 ...
- dotweb——go语言的一个微型web框架(一)
dotweb是16年正式托管到github的一个开源项目,go语言的web框架目前也有很多,出名的有bee和echo.它们都是很优秀的框架,但是我们喜欢更轻.更小的东西,经历一些之后我们更青睐微服务这 ...
- 利用python web框架django实现py-faster-rcnn demo实例
操作系统.编程环境及其他: window7 cpu python2.7 pycharm5.0 django1.8x 说明:本blog是上一篇blog(http://www.cnblogs.co ...
- 【Flask】微型web框架flask大概介绍
Flask Flask是一个基于python的,微型web框架.之所以被称为微型是因为其核心非常简单,同时具有很强的扩展能力.它几乎不给使用者做任何技术决定. 安装flask时应该注意其必须的几个支持 ...
- web框架。Django--
一,DIY一个web框架 1.1什么是web框架 1.2用socket模拟B-S的服务端 1.3,浏览器端的network查看 1.4,request格式 1.5,response格式 1.6,初识w ...
随机推荐
- 6月5日 python学习总结 jQuery (二)
1. 操作样式 对CSS类的操作: addClass();// 添加指定的CSS类名. removeClass();// 移除指定的CSS类名. hasClass();// 判断样式存不存在 ...
- /proc/uptime参数的意义
有关/proc/uptime这个文件里两个参数所代表的意义: [root@app ~]#cat /proc/uptime 3387048.81 3310821.00 第一个参数是代表从系统启动到现在的 ...
- 利用MSSQL getshell
此次复现使用的sql server 2000 和sql server 2008两个环境进行的 是在已知数据库密码的基础上进行的 0x01 MSSQL连接 连接MSSQL 2000 新建连接: 填写目的 ...
- python 发送GET请求
# #博客地址:https://blog.csdn.net/qq_36374896 # 特点:把数据拼接到请求路径的后面传递给服务器 # # 优点:速度快 # # 缺点:承载的数据量小,不安全 imp ...
- 如何做一个网站 (C# + MVC Web+ easyUI )
如何做一个网站 小编想做一个网站,采用技术为:C# + MVC Web+ easyUI 小编经过几天的学习,以及指了几位大神指导,初见效果.建立网站的思路:先列举需要用到了几个知识点,然后逐一攻克,然 ...
- 知识点简单总结——Pollard-Rho算法
知识点简单总结--Pollard-Rho算法 MillerRabin算法 用于对较大(int64)范围内的数判定质数. 原理:费马小定理,二次探测定理. 二次探测定理:若 $ p $ 为奇素数且 $ ...
- 如何集成 Spring Boot 和 ActiveMQ?
对于集成 Spring Boot 和 ActiveMQ,我们使用依赖关系. 它只需要很少的配置,并且不需要样板代码.
- 使用 Spring Cloud 有什么优势?
使用 Spring Boot 开发分布式微服务时,我们面临以下问题 与分布式系统相关的复杂性-这种开销包括网络问题,延迟开销,带宽问题,安全问题. 服务发现-服务发现工具管理群集中的流程和服务如何查找 ...
- 电源PCB布板的10个基本法则
电容模型 电容并联高频特性 电感模型 电感特性 镜象面概念 高频交流电流环路 过孔 (VIA) 的例子 PCB板层分割 降压式(BUCK)电源:功率部分电流和电压波形 降压式电源排版差的例子 电路等效 ...
- post提交的数据有哪几种编码格式?能否通过URL参数获取用户账户密码
这里是修真院前端小课堂,每篇分享文从 [背景介绍][知识剖析][常见问题][解决方案][编码实战][扩展思考][更多讨论][参考文献] 八个方面深度解析前端知识/技能,本篇分享的是: [post提交的 ...