我的第一个开源项目|Geex:道阻且长的开源之路

投稿作者:Lulus 杨树

GitCode 平台 G-Star 孵化项目 Geex 项目作者

我想在工作之余,为开源世界做出一点微小的贡献。

1.梦想的起点:牛马搬砖的痛与最佳实践的渴望

在我深入体会多年国内软件的开发生态的过程中, 我逐渐发现了一个残酷的现实:

众多优秀的开发者被困在"营养不良"的代码海洋中逐渐麻木成为了牛马。

这不仅仅是技术问题,更是一种集体的困境。

😭那些痛的领悟

时下流行着很多的开发框架 SpringBoot、Asp.Net、Django、Flask、Ruby on Rails 等, 它们提供了无限的可能性。

但是,由于开发者技术背景的不统一,同时随着项目复杂度增加,这种无限的可能性似乎开始引发了一种混乱。

微服务、三层架构、DDD、MVC、ORM、IOC、AOP 等概念交织,各种网关、子服务、Service、Provider、Manager、Repository、Controller、UnitOfWork、Authentication、Authorization 等实现混杂,因为框架缺乏统一的最佳实践,团队成员在各自引入新功能时各自"hack"。

最终,一个看似简单的功能实现,背后可能隐藏着好几个微服务或者引用项目的调用链,混杂了N种风格的代码;系统成为了混沌,debugging 变成了考古,我们越来越不敢改动代码,甚至懒得再去理解代码,我们疲于应付各种配置问题、脏数据、环境差异,调试一整天到处埋点只为分析一个调用链,取巧变成了对付 Deadline 的唯一手段,我们开始"理解""屎山",最终加入了"屎山"。

🤕对最佳实践的渴望

每当我为了实现一个简单功能而编写大量模板代码,捏着鼻子复制粘贴各种配置各种 Service 各种 Get、Set 方法时,一种强烈的不公感就会涌上心头。

编程应该是创造的过程,我们应该享受创造的乐趣,而不是受困于繁琐和重复。

这种矛盾日积月累,我开始思考:是否有一个真正以开发者体验为中心的框架?

  • 它自带全功能的最佳实践的范例,一键部署,不再需要繁琐的环境搭建,能让初中级开发者也能就地开码
  • 它有丰富的开箱即用的模块,不使用模块时不会增加系统复杂度,使用时只需要简单增加几行代码
  • 它不囿于三层架构,可以快速开发单体,也可以升级为微服务且无需重写代码

这就是 Geex 诞生的原点,它源于"Geek",我用"x"替换了"k",寓意着打破常规,探索技术的无限可能------它是我对现状的不满,是我对最佳实践的渴望。

2.Geex 的核心理念:让开发者不再困于"思考"

当我开始设计 Geex 时,我只有一个想法,作为开发者,要觉得"爽",这种"爽"来源编码时的不假思索,所谓"放弃思考"。

✅不需要思考这个文件该放在哪个文件夹

在传统开发中已有的所谓模块化开发设计,随着项目的增长,代码库往往会扁平地扩展一系列的文件夹,它们之中既有公共能力模块(Logging/Localization/Caching...) 也有业务模块(Order/Product/Shipping...),最后两者互相混杂,新加入的开发者需要数周时间才能理解代码组织方式。

于是我把所有的能力模块都独立到了项目以外,统一封装成了 Package,同时对业务模块尽量采用了自解释的项目结构:

因为篇幅有限无法精确到每个具体的项目文件,详细的项目结构可以参考:

✅不需要思考前后端需要对接哪些字段

Geex 致力于解决前后端对接困难互相甩锅的困境。

传统 REST API 是目前大多数开发者的默认选择,但它的局限性也越来越明显:前端常常需要多次请求才能获取所需数据,API版本管理复杂,文档维护成本高。

我选择了 GraphQL 作为 API 层的核心技术。它让后端定义后端接口的最大上限,同时允许前端简短且精确地描述所需数据结构,同时还自带文档和类型检查。

同时 Geex 实现了前后端传输模型的一键同步,后端的枚举/常量等也能够无缝传递到前端UI层。

我记得曾在 Geex 中实现一个复杂的嵌套查询,一个 GraphQL 查询替代了原本需要四五个 REST API 和大量后处理代码的场景,那种畅快感让我确信这是正确的选择。

✅不需要思考数据库字段用什么类型

Geex 致力于消灭代码到数据库层面的类型映射鸿沟。

存储层面,MongoDB 的文档模型与业务对象的自然映射消除了传统 ORM 中的"阻抗不匹配"问题。不再需要复杂的表关系设计,不再需要繁琐的 JOIN 查询,业务对象可以直接序列化存储,这大大简化了数据访问逻辑。同时 Geex 提供了强力的对 MongoDB 的"EntityFramework",在性能不变的情况下实现了 EF Core 的几乎所有功能,甚至提供了更强大的 LINQ 查询能力。

✅不需要思考新建模块的成本

Geex 致力于消灭一切可能重复的配置、代码。

  • 创建一个模块只需要一个插件命令,所有的 API、权限、配置、数据模型、业务逻辑都可以自动生成,生成出来的模块在包含增删改查所有功能的前提下不超过 200 行代码,整体代码的 Maintainability Index 超过 92
  • 平均构造函数注入依赖不超过两个
  • 所有的配置都带有一个直观的默认值,不需要显式配置

这样的代码结构让业务逻辑清晰可见,每个操作的权限需求和数据流动一目了然。更重要的是,这种模式天然支持单元测试,提高了代码质量和可维护性。

✅不需要死记硬背Magic字符串

Geex 致力于"枚举一切"。

以权限控制为例,权限字符串的维护常常是企业应用的痛点。传统方案要么过于简单无法满足复杂业务需求,要么过于复杂难以维护。在 Geex 中,我设计了一种基于枚举的权限系统,开发人员不需要在文档中检索权限字符串,只需使用枚举类型即可:

权限定义与使用分离,让权限控制成为系统即插即用的功能,而不是事后在每个方法内增加一个 if 的附加物。这种方式还支持权限的可见性控制和继承关系,甚至支持单个字段级别的权限控制,满足了从简单到复杂的各种权限场景需求。

✅不需要考虑环境不一样跑不起来怎么办

最后,Geex 通过一系列脚本和配置,实现了从开发环境搭建到生产部署的全流程自动化。

初始化工作区、切换引用类型、容器化部署,这些原本繁琐的任务都被简化为单个命令,同时和 vscode 深度集成,你甚至不需要使用命令行。

这种"一键式"体验不仅提高了开发效率,也大大降低了新团队成员的入门门槛和运维的复杂度。

不需要考虑多租户怎么实现,数据过滤怎么搞,异步任务怎么弄......Geex 带来一站式解决方案,你想要的它都有。

3.从 0 到 0.25:技术难点与隐藏的坑

从最初的构想到第一个可以在生产环境使用的版本,这条路比我想象中要崎岖得多。 GraphQL 与 MongoDB 这对"神仙组合"虽然强大,却也藏着无数的技术陷阱。

😣MongoDB 的表达式树地狱

针对 MongoDB,我曾预想过表达式解析会有点复杂,却没想过中间涉及的缓存、时序等问题会让它变得"那么"复杂。

为了支持这样的查询转换为 MongoDB 的聚合管道,我不得不钻研表达式树的每一个细节,甚至为了实现一个小功能熬夜到凌晨是家常便饭。总代码量数万行,而且大部分都是极其晦涩的逻辑,为此增加了几百个测试用例。

现在它会被翻译成 MongoDB 的聚合管道,支持复杂的查询、排序、分页:​

🪄GraphQL 的 Loader 魔法与代价

在 GraphQL 层面,N+1 查询问题曾让我头痛不已。一个看似简单的嵌套查询可能导致数据库被疯狂访问:

为了解决这个问题,Geex 实现了一套基于表达式树的 LazyLoad 和 BatchLoad 机制。这套机制能自动合并相关查询,将 N+1 查询转化为单次批量查询,性能提升了数十倍。实现它的过程?又是无数个"我为什么要自找苦吃"的夜晚。

终于,现在它可以通过一个简单的调用链来实现:

✌️class 枚举与类型安全的胜利

最让我满意的是一套自建的 class 枚举生态系统。在传统框架中,权限检查、配置项、常量定义常常散落在字符串常量中,导致重构噩梦:

当重构一个大型项目时,第一种方式几乎无法保证所有引用都被正确修改,甚至还有更恐怖的字符串拼接,而第二种方式,相信编译器会成为你最好的朋友。

4.从 0.25 到 0.5:小圈子的成功时刻

构建 Geex 的过程,是我与那些日常开发痛点不断对话的过程。每一个设计决策背后,都有无数次"如果框架能这样做就好了"的场景驱动。

当我最终完成第一个可用版本并在组内成功推广时,组内的反响:

"啊?只需要引用项目,接口就可以直接用了吗?不需要配路由吗?我天!?"

"啊?生成器生成完了就可以直接跑起来调增删改查了吗?我天!?"

"啊?这个枚举是自动生成的?前端怎么什么代码都没写就可以用这个枚举啦?不用拷贝一份吗?我天!?"

"啊?F1一下就全跑起来啦?不需要配一下数据库和 Redis ?我天!?"

"啊?直接就能用 https 啦?我天!?"

"啊?...我天!?"

在大家不断的感叹中,我获得了前所未有的满足......

🔥实战案例:"加速"一个迭代

当然,框架的真正价值在于实际项目中的应用。有一次我们接到一个紧急需求:给公司的客户管理系统增加一个完整的订单追踪模块,从前端到后端的集成估时 3 周,但实际只给了 1 周的时间。

传统开发流程可能是这样的:

1.创建项目并设计数据库表结构(1天)

2.后端编写 REST API 接口(1天)

3.前后端根据沟通接口(贯穿始终...)

4.后端编写实体类和映射配置(1天)

5.后端实现仓储层和服务层并部署到 dev 环境(2天)

6.前后端联调(1天)

每一次前后端的沟通都可能导致接口变更,需要更新接口文档、重新发布 dev 环境,甚至需要手动更新数据库表结构。

而使用 Geex 实际走的流程是:

1.后端执行生成器命令创建订单追踪模块(10分钟)

2.后端定义新的实体类, Gql 自动更新接口字段(4小时)

3.前端直连后端开发机(得益于 Geex 独特的基于 SwitchHosts 的开发时域名解析),即时获取最新的类型提示开始开发(无需等待)

4.后端根据业务需求完善逻辑(1天)

5.前后端联调(1天)

前端开发可以立即看到后端最新的 API 定义,按需读取实体的字段,不需要等待接口文档,不需要等待 dev 环境发布,不需要考虑数据库结构变更。

产品经理原本已经做好了延期的准备,结果前端在第一天就根据最新的类型提示开始开发,后端 3 天就完成了全部开发,包括测试。工作量只有传统开发流程的 1/3。

这种效率提升不是靠加班,而是通过消除了传统开发中各种不必要的摩擦和冗余。

5.从 0.5 到 1:社区推广的坎坷之路

鉴于同事们的广泛好评,我决定把 Geex 推向更广阔的舞台。毕竟,再好的工具,如果只关在一个团队的小圈子里,也只是一段孤芳自赏的代码罢了。

为此我小熬了几次夜,编写了一份我认为还算详尽的文档(虽然回头看确实有点混乱),准备了好些示例和快速入门教程,添加到了文档里面。

过了好久,终于下定决心,录制上传了第一个介绍 Geex 的视频,期待着评论区的技术交流。结果------100 播放,3 个赞,0 条评论。

不要气馁!第二个视频展示了如何快速实现一个全栈 CRUD,成绩更"惊人":80 播放,1 个赞。

好像不太妙。

我反思了很久:是不是视频做得太差?是不是介绍得不够清楚?还是说,我其实没必要推广这么一个框架?

人生不会只有代码,工作变动、生活琐事还有新项目上线------这些都成了 Geex 发展路上的绊脚石。我曾想过放弃,毕竟一个没什么人关注的开源项目,似乎不值得投入那么多心血。

当然如果你好奇这个框架到底是什么样,可以看看这个"孤独的视频":

从≈零开始:Geex Start_哔哩哔哩_bilibili

6.至暗时刻与重燃希望

Geex 的代码仓库慢慢积灰,提交记录从每天数次变成了一两个月才一次。有时打开项目,看着那些还想完善的功能设计,却不知从何处继续。

直到最近,当我处理一个复杂的业务需求时,不得不再次面对那些我曾试图用 Geex 解决的老问题:重复的配置、混乱的代码组织、难以维护的权限系统......

于是我重新打开了尘封的 Geex 的项目,从那边拷贝了一两个功能片段,只能说 Geex 里面的代码还有些参考意义,至少对我而言是如此。

7.向风车挑战的未来之路

时间可能是最大的敌人,但是我想重拾代码的激情,就像是 30 多岁的中年男人下班打两把游戏,虽然老是对线被杀成 0-2 然后龟塔,但还是会忍不住想要继续玩下去。

每一个开源项目背后,都有一个不断与自我怀疑对线的开发者。这条路上没有终点,只有不断的迭代和改进。

Geex 的故事并不特别,但它承载了我对软件开发应有模样的理解和追求。搞开源的大多数人都是些许疯狂的堂吉诃德,可能背着房贷供着家庭,对抗着那些看似不可战胜的现实风车,顺便希望能为这个世界做出一点微小的贡献。

📅Geex的未来规划

回顾过去的迭代历程,我对 Geex 的未来有了更加务实的规划:

  1. 功能优化:继续完善 Geex,更多的功能,更爽的用法,更好的性能,更少的 bug......
  2. 文档建设:重构官方文档,提供更详细的入门教程和示例代码,特别是针对从传统框架迁移的场景
  3. 示例项目:构建多个完整的企业级应用示例,涵盖从权限管理到工作流、报表等典型企业场景
  4. 工具链完善:增强 VSCode 插件和相关工具链,进一步简化开发流程
  5. 社区建设:构建更多的交流渠道,收集反馈和贡献

❓如何参与 Geex

如果你读到这里,对 Geex 产生了一丝兴趣,我非常欢迎你以各种方式参与进来:

也许 Geex 永远不会成为某知名框架,但对我来说,它几乎陪伴了我的整个程序员生涯,也已经成功地改变了某几个开发者的编码体验,这或许就是开源项目最大的意义。

项目地址👇:

https://gitcode.com/geexcode/geex

致谢💗:@罗老师 @梁老板 @李总 @MrKKK @韩东 @所有支持过我的人

相关推荐
一个处女座的程序猿14 小时前
AI之Agent之VibeCoding:《Vibe Coding Kills Open Source》翻译与解读
人工智能·开源·vibecoding·氛围编程
一只大侠的侠15 小时前
React Native开源鸿蒙跨平台训练营 Day16自定义 useForm 高性能验证
flutter·开源·harmonyos
IvorySQL16 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
一只大侠的侠17 小时前
Flutter开源鸿蒙跨平台训练营 Day11从零开发商品详情页面
flutter·开源·harmonyos
一只大侠的侠17 小时前
React Native开源鸿蒙跨平台训练营 Day18自定义useForm表单管理实战实现
flutter·开源·harmonyos
一只大侠的侠17 小时前
React Native开源鸿蒙跨平台训练营 Day20自定义 useValidator 实现高性能表单验证
flutter·开源·harmonyos
晚霞的不甘18 小时前
Flutter for OpenHarmony 可视化教学:A* 寻路算法的交互式演示
人工智能·算法·flutter·架构·开源·音视频
晚霞的不甘19 小时前
Flutter for OpenHarmony 实现计算几何:Graham Scan 凸包算法的可视化演示
人工智能·算法·flutter·架构·开源·音视频
猫头虎19 小时前
OpenClaw-VSCode:在 VS Code 里玩转 OpenClaw,远程管理+SSH 双剑合璧
ide·vscode·开源·ssh·github·aigc·ai编程
一只大侠的侠19 小时前
Flutter开源鸿蒙跨平台训练营 Day12从零开发通用型登录页面
flutter·开源·harmonyos