手把手带你写一个 Web 框架
叶剑峰
腾讯高级工程师,前滴滴技术专家
22731 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 42 讲
特别放送 (1讲)
手把手带你写一个 Web 框架
15
15
1.0x
00:00/00:00
登录|注册

13|交互:可以执行命令行的框架才是好框架

好处和原因
Kernel 接口返回 http.Handler
创建 http.Server 并启动 Web 服务
获取 Web 引擎
挂载框架和业务的 Command 到根 Command
创建根 Command
绑定各个服务到服务容器
初始化服务容器
开发业务需要的命令行工具
设计命令行工具
将进程启动改成调用命令启动 Web 服务
引入 cobra 库
接口设计改动
Web 服务启动改造
框架的设计改动
框架的扩展可能性
框架改造成命令行工具
总结

该思维导图由 AI 生成,仅供参考

你好,我是轩脉刃。
上一节课,我们开始把框架向工业级迭代,重新规划了目录,这一节课将对框架做更大的改动,让框架支持命令行工具。
一个拥有命令行工具的框架会非常受欢迎。比如 Beego 框架提供了一个命令行工具 Bee、Vue 框架提供了 Vue-CLI,这些工具无疑给框架的使用者提供了不少便利。在使用框架过程中,命令行工具能将很多编码行为自动化。
而且退一步说,在实际工作中你会发现,即使用的框架没有提供任何命令行工具,在业务运营的过程中,我们也需要开发各种大大小小的命令行运营工具,作为业务运营的必要辅助。所以一个自带命令行工具,且很方便让用户自行开发命令行的框架,是非常有必要的。
这节课我们就研究一下如何将 hade 框架改造成为支持命令行交互的框架。

第三方命令行工具库 cobra

要让一个程序支持命令行,那么它的核心功能就是要能解析参数,比如 ./hade app start --address=:8888 其中的 ./hade 是我们要运行的程序,而后面的 app 和 start 两个字段以及–address=:8888 就是这个程序对应的参数了。
那么如何解析参数呢?
Golang 标准库提供了 flag 包能对参数进行解析。但是 flag 包只是一个命令行解析的类库,不支持组织,所以如果想基于 flag 包实现父子命令行工具,显然就不够了。出于不重复造轮子,站在巨人肩膀上的想法,我们将视线移向开源社区一个最出名的命令行工具库 cobra
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

本文介绍了如何使用 cobra 库将框架改造成支持命令行交互的工具。作者首先强调了命令行工具对框架使用者的便利性和在业务运营中的必要性。随后详细介绍了 cobra 库的核心数据结构和常用属性设置,并通过示例代码和输出结果图展示了如何使用 cobra 来初始化命令和子命令,并设置命令的关键字段和执行函数。文章重点介绍了如何利用 cobra 库实现框架的命令行交互功能,为读者提供了一种实用的技术方案。同时,还提出了在框架中引入 cobra 库的方法和对 Command 结构进行修改的具体步骤,以及如何增加框架的交互性。整体而言,本文为读者提供了一种利用 cobra 库改造框架的实用指南,帮助读者快速了解并实践命令行交互功能的实现。文章通过示例代码和输出结果图展示了如何使用 cobra 库来初始化命令和子命令,并设置命令的关键字段和执行函数。同时,还提出了在框架中引入 cobra 库的方法和对 Command 结构进行修改的具体步骤,以及如何增加框架的交互性。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《手把手带你写一个 Web 框架》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(13)

  • 最新
  • 精选
  • 芒果少侠
    思考题: 高层抽象不应该依赖于实现。这也是为了方便业务侧能够自由地选择httpHandler实现(不仅仅是gin)

    作者回复: 是的,抽象脱离具体的实现的考虑。

    2021-10-17
    2
    3
  • 芒果少侠
    也就是说,我们只能根据 Command 拿到服务容器,那怎么拿到 Gin 函数创建的 Engine 结构呢? ----- 其实,也可以把httpHandler/*gin.Engine filed直接加到command的结构体中中,这样就不需要绕一个圈子从serviceProvider中拿到Engine结构了。 当然,上述思路可行但不一定优雅。framework框架层在运行时是可能需要各种服务的,因此直接注入服务容器container是一个更好的办法。这样之后可以直接从服务容器中获取不同的“服务提供方”,而不仅仅局限于一个*gin.Engine。

    作者回复: 其实思路就是所有获取的东西尽量通过服务容器来获取。这样由服务容器来统一管理所有服务。

    2021-10-17
    2
  • 终于到这里了 最爱的环节之一 之前的service provider 让我神清气爽

    作者回复: 哈哈,命令行后续的想象力其实很大,可以想象很多的快捷功能

    2021-12-08
    1
  • 宙斯
    问题:之前的返回值是返回了 *gin.Engine。而现在的返回值是返回了 http.Handler,其他的实现没有任何变化。你能看出这样的改动相较之前有什么好处么? 回答: http.Handler这是接口类型,接口需要实现ServeHTTP(ResponseWriter, *Request)方法,采用返回http.Handler是解耦engine,若有必要可以替换gin.engine为其他engine(实现了ServeHTTP方法),这也提现面向接口编程的好处,而非具体类型(例如gin.engine)。

    作者回复: 是的,接口能实现解耦合

    2021-10-24
    1
  • qinsi
    似乎是想要app能够使用被集成到核心框架里的不同的web框架,而使用了不同web框架的app可以共享一些核心框架提供的服务,比如可以自定义命令行子命令生成不同类型项目的脚手架等。有些好奇这个方案有没有实际的使用场景,因为看上去不管是整合已有的web框架还是已有的app都存在一定的工作量,不确定整合带来的好处会大于这些工作量。

    作者回复: 命令行工具是有具体的使用场景的。比如运营管理系统。而且命令行逻辑和app的逻辑有很多是可以复用的。单独写一个命令行工具项目也是可以的,但是整合会节省很多复用逻辑

    2021-10-16
    1
  • 抽象 反正替换成其他的 是基于net/http实现的都行

    作者回复: 是的,抽象,不依赖实现

    2021-12-08
  • Geek_cbab11
    看到现在没有一个明确的框架启动、服务注册流程,在context中实现请求和响应也就算了,在route中也是各种进行服务的注册,solid原则完全没有,代码过于混乱,实在是看的头疼
    2022-02-10
    15
  • Geek_cbab11
    在业务层console/kernel 加载框架级别的command,这种操作真头疼
    2022-02-10
    1
    4
  • Geek_2b09c4
    这份代码里有个bug,大概就是在NewHttpEngine那里,main里的container还没加到engine里就开始注册demo,demo被注册到了engin初始化时得到的container里。 但是这个container和main里一开始定义container不是同一个东西,后面bind的时候engin里的container被main的container覆盖了,进而导致demo的注册丢失了。 所以会出现demo2运行不了的情况。
    2022-11-17归属地:广东
    2
    2
  • 姜波
    课程源码,请求/demo/demo2报contract demo have not register,不知道咋回事
    2021-10-30
    7
    1
收起评论
显示
设置
留言
13
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部