自己在学习 Golang 的时候,心血来潮写了 GoGym,一个简洁灵活的 RESTful 微框架

2017-03-13 18:33:04 +08:00
 leontung

受 PHP 框架 Laravel 的启发, GoGym 兼顾了代码的简洁易用性 框架解决的需求是

  1. 只需要定义一个 Controller 并且在注册了之后,可以定义任意数量的 Action ,只需要将其和路由还有方法匹配好
  2. 用户只要返回结果,自动生成 JSON 格式的 response

示例代码:

type IndexController struct {
}
func (IndexController *IndexController) Index(values url.Values, headers http.Header) (statusCode int, response interface{}) {
	return 200, map[string]string{"hello": "world"}
}
func main() {
	var apiService = GoGym.Prepare()
	apiService.Get("/", "IndexController@Index")
	apiService.RegisterController(&IndexController{})
	apiService.Serve(3000)
}

可以看到,我们只需要上面短短的 11 行代码,就能起一个 hello world 的 RESTful 服务

欢迎大家发 issue 或者邮件来讨论不足的地方,让我可以改进,也可以提交 feature requirement ,如果觉得不错也欢迎 star

项目地址: https://github.com/ZhenhangTung/GoGym

八卦一下,起这个项目名字就是因为自己喜欢去健身房,对自己也是一种督促,也希望大家多多运动保重身体,敲代码是产出的话,休息运动就是给自己充值了。

共勉!

1733 次点击
所在节点    Go 编程语言
15 条回复
taowen
2017-03-14 08:52:13 +08:00
支持一下,造轮子不容易
leontung
2017-03-14 13:59:50 +08:00
@taowen 十分感谢!大家一起加油💪
jarlyyn
2017-03-15 15:56:27 +08:00
看不懂。

这是要注册个 controller 类,实现 controller interface ?

直接用 httprouter 就可以了啊

var jsonAction = func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
body, _ := json.Marshal(map[string]string{"hello": "world"})
w.Write(body)
}
router := httprouter.New()
router.RedirectTrailingSlash = false
router.RedirectFixedPath = false
router.GET("/test", jsonAction)
http.Handle("/controller/", http.StripPrefix("/controller", router))
http.ListenAndServe(":3000", http.DefaultServeMux)
jarlyyn
2017-03-15 16:10:36 +08:00
要说看得出来的问题的话,感觉以字符串形式传 action 太坑

及不能类型检测,不能错误检查。
leontung
2017-03-15 22:57:15 +08:00
@jarlyyn 十分感谢!我之前都没发现有 router 这么厉害的项目。
我是在学习过程中,发现 Golang 很多 web 框架,比如 echo 等,都会先预定好一些方法( Action ),比如在 Controller(有些框架定义为 router)中有 GET , POST 等方法来接收 GET 和 POST 等请求,这样很不错,也符合 Golang 的语言特性,但我觉得不太能满足业务需求,如果我有一个 Controller ,就是负责首页逻辑的,需要接收 2 个 GET 方法,按照目前我的理解来看,我就要创建两个 controller 了。
我解决的事情是,只需要建立一个 Controller ,下面可以定义无数个 Action 。
用 apiService.Get("/", "IndexController@Index")注册了后,在底层就会生成一个包含 http request , route , Controller , Action 的 map ,最后我用的是 reflect 去调用所有的 Action 。
你提到的类型检测,不能错误检查这两点我会考虑并且看看怎么加入。
jarlyyn
2017-03-15 23:51:01 +08:00
@leontung

一个 router 就是一个控制器。

想一想,写 web 为什么一定要有控制器类呢?

方法 /函数本身就可以作为变量,所以其实不一定需要控制器类这个概念。

还有就是。

要代码补全的话,直接吧 action 传进去就可以了。

比如

indexController:=&IndexController{}

apiService.Get("/", indexCroller.index)
jarlyyn
2017-03-15 23:53:34 +08:00
@leontung

以我的 blog 为例

https://gist.github.com/jarlyyn/57ac8e2dc950e9c7715de27149481319

用了两个 router

其实不就等于是两个控制器?
leontung
2017-03-16 11:00:00 +08:00
@jarlyyn 的确没有任何规定要规定大家都用 controller class ,然后在里面定义一系列 method 作为 action 来开发项目呢,就像写代码也不一定要用 OOP 思想来写。这些思想需要我们在某些前提下讨论。
如果我写一个小项目(我觉得自己的个人博客也算其中之一吧),或者小脚本,不管是 golang , php 还是 js ,以我目前的浅薄的开发经验,都不需要建立 class ( Golang 里是 struct ),搞个 class 来有时甚至只是种累赘。
但如果我们的项目发展到一定程度了呢,有同事朋友或者其他开发者参与进来了呢,考虑的不只是实现了,我们还要考虑 organization ,往大一点说就是架构,考虑他人的开发感受,我认为这就是会有各种设计模式的原因吧,大家在同一个 convention 下开发(注意,我没有用 law 这个词)。
我的小项目目标是“ RESTful API ”。
扯开点说,代码除了代码本身的语法和规定,怎么写都是大家自己的决定, free style 都可以,只是在每个情景之下都会有 pros&cons ,是适合不适合的问题,并没有对错。
---
我:PHP 是世界上最好的语言,不是吗?
A:Java 才是
B:Bullshit!
....
2333~
jarlyyn
2017-03-16 11:59:54 +08:00
@leontung

middleware 本身就是一种组织形式啊。

不过是组件化 Vs 继承罢了。

从某种角度来说,使用控制器类并不一定适合,或者从我的经验来看不适合大规模的项目。大项目最简单的降低难度的方式就是拆散。调试 /继承中间件在这个情况下比调整控制器类容易的多。

当然,这点并不重要。我只是一些建议和意见罢了。

我只是在写了几年 php 后歪到 nodejs 去了,受 express/koa 影响多了,觉得 middleware 型的框架水到渠成罢了。
leontung
2017-03-16 19:09:22 +08:00
@jarlyyn 嗯嗯,理解,你的建议很棒,我自己已经开好了 issue 着手改造了。
我是写了 PHP 最近因为公司业务需求歪到了 Golang 哈哈哈。
leontung
2017-03-16 19:13:48 +08:00
@jarlyyn middleware 我还不是特别熟悉,在 laravel5 引入了 middleware 时候我一直在用 Phalcon 写业务,没有机会去学,我去调研学习一下这个概念
102400
2017-04-10 02:29:37 +08:00
Laravel 本身比很多 web 框架都要麻烦复杂得多,用它的方式写 go 还不如不要
leontung
2017-04-11 22:50:09 +08:00
@102400 嗯嗯,在研究 Laravel 源码时候,拿路由举例,它使用了一些 Symfony 路由中的 Compile ,然后拿到结果自己再处理,我个人认为太复杂,所以我自己在实现路由时候并没有用那一套。
102400
2017-04-12 00:56:43 +08:00
@leontung Ruby 的 Sinatra 几乎是这类框架的典范,可以参考下
leontung
2017-04-12 18:41:14 +08:00
@102400 谢谢指教!不过我现在还不会 Ruby ,阅读细节可能会比较费劲,可以看下大局的思路

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/347155

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX