HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

通过基于 Go 的微服务框架 goa,实现对服务 API 的定义、审查与实现

  • 2016-01-05
  • 本文字数:3755 字

    阅读完需:约 12 分钟

Raphael Simon 是来自于 RightScale 的一位高级系统架构师,他创建了一种基于 Go 语言的 HTTP 微服务框架,名为“goa”。这一框架允许开发者通过领域特定语言(DSL)定义服务的API,并且通过自动代码生成功能创建“样板”式的服务端和客户端代码以及文档。

Raphael 在他的博客 Gopher Academy 上发表了一篇介绍 goa 框架的帖子,他提到 RightScale 的工程师团队正在将一个一体性的 Ruby on Rails 应用迁移为一系列基于 Go 语言创建的微服务应用。这次迁移工作的一个主要挑战在于如何创建设计良好的服务 API,为了支持整个微服务 API 的设计、审查以及实现,他们创建了一系列的工具。这一项目所产生的结果之一就是基于 Go 语言的框架 goa 的诞生,它的出现受到了在 RightScale 中所应用的一个基于 Ruby 的 API 开发框架 Praxis 的启发。

InfoQ 与 Simon 进行了一次访谈,他既是 RightScale 的高级系统架构师,也是 goa 的主要贡献者之一。这次访谈主要问及了关于goa 这一微服务框架的设计目标、使用方式以及未来的发展计划。

InfoQ:欢迎你 Raphael!请你为读者说明一下“goa”是个怎样的产品,以及创建这一架构的动力是什么。

Simon:RightScale 正在向微服务风格的架构进行迁移,这项工作已经开展了一段时间了,而最近一段时间团队开始使用 Go 语言编写部分服务。总体来说,无论在开发还是运维方面,Go 都证明了它是一个优秀的选择。这门语言很容易上手,并且所创建的服务表现也很出色。

不过,采用 Go 语言进行开发也意味着在开发与部署阶段要引入一种新的技术栈,因为直至最近,RightScale 基本上都是使用 Ruby 进行开发的。团队在创建与运行 REST API(RightScale 已经将这一使用 Ruby 语言打造、用于创建 REST API 的 Praxis 框架开源了)方面已经具备了丰富的经验。由于目前还没有一种现成的解决方案可以应对我们的需求,因此有理由运用这些经验去打造基于一种 Go 语言的服务开发栈。

这项工作的成果就是 goa 的诞生,它是一个微服务的开发框架,通过它能够以代码的方式描述 API 的设计。与 goa 框架一同推出的还有一个 goagen 工具,它能够通过设计代码生成各种输出,包括 http 服务器的封装、代码脚手架、文档、客户端,甚至是自定义的输出。goa 包还包括大量的支持性模块,服务本身与生成的代码都能够利用这些模块进行服务的实现。

InfoQ:与使用标准的 Go 类库(或者使用 Peter Bourgon 开发的 go-kit)相比,“goa”通过怎样的方式简化了微服务的开发?

Simon:goa 框架能够描述 API 的 _ 意图 _。通过使用 goa 设计语言,开发者能够定义 API 所暴露的资源与行为(即 API 的终结点)。对于每种行为的描述包括所期待的请求状态,以及各种可能产生的响应。这种方式能够带来许多益处:举例来说,它在设计阶段就能够起到很大的作用,各个团队能够通过 Swagger UI 生成 Swagger 的规格说明,从而提出反馈意见。这一反馈循环能够为负责生成 UI 或编写面向用户的文档的团队带来极大的便利。最大的优点在于,这一切都发生在实际编写代码实现之前。

这种方式的另一优点在于,一旦设计完成之后,goa 就将负责生成所有样板逻辑,包括请求的验证以及用于描述请求状态的自定义数据结构。这样一来,设计就变成了实现所必需的一部分。这就体现出了这一方式具有很高价值的一面,否则的话,维持实现与设计之间的同步就成了非常一项非常繁琐的流程。对于每个暴露了访问功能的行为来说,goa 能够生成特定的请求处理逻辑的上下文,从中返回符合设计所描述的数据结构。这种做法减少了对“绑定”方式的需求,也不必手动地验证所传入的请求的格式。

goagen 也能够为 API 生成相应的客户端,包括一个命令行工具、Go 包和 JavaScript 的客户端。这种方式显而易见的好处是免去了手动进行这一过程所花的时间,除此之外,它还有助于维护多个客户端之间的一致性,并且保持他们与 API 的同步。在微服务的世界中,服务的数量是持续增长的,因此保持他们之间的一致性是一种非常有价值的做法,它大大地简化了构建整合的流程。

InfoQ:“goa”看起来为开发者提供了很多内容,包括一个运行时“引擎”、支持日志记录、能够对“中间件”进行自定义、还支持错误处理。你是否打算为基于 Go 的微服务架构提供一个单一的解决方案?

Simon:goa 中的请求上下文是运行时引擎的核心,它引用了 golang 这个包的开发者所做的工作,主要是跨接口传递上下文的功能,从而实现一些强大的特性,例如设置 deadline,以及在 goroutine 之间共享状态信息。举例来说,上下文信息能够一路传递至负责生成外部请求的软件模块,因此,在整个周期中的任何阶段,都能够获取包括 deadline 在内的整个请求状态。生成的代码将以一种特定于行为的数据结构对上下文进行封装,通过在设计代码中所描述的字段暴露已验证的请求的状态。

而其余部分的行为都是能够进行替换的:goa 的设计遵循了“提供内置支持”的模型。举例来说,如果你对于如何进行错误处理并没有非常确定的想法,那么 goa 将为你提供一种恰当的默认实现(在这种情况下所返回的响应将包括 500 状态码)。不过,开发者也能够方便地覆盖默认的错误处理逻辑,以实现任何自定义的逻辑,goa 还提供了一种备选的错误处理逻辑,在响应中将不包括调用栈的信息。另一个例子是对中间件的支持:goa 定义了一种专用类型的中间件,可以通过它利用丰富的上下文信息,但同时也能够使用普通的 http 中间件。

目前来说,并非所有特性都能够被轻易地替换(例如日志记录),因为 goa 最初的关注点在于代码的生成。总体目标是提供一个完整的、模块化的微服务开发框架,因此,曾使用过 go-kit 或其它 Go 包的开发者依然能够继续使用它们,而同时又能够受益于 goa 所提倡的基于设计的 API 设计方式。

InfoQ:我们很有兴趣了解一下关于生成能够调用服务 API 的客户端代码的特性。通常来说,有关代码生成的讨论总是会得到一些消极的回应,例如生成的代码过于复杂,或是生成过程不够透明、也无法进行自定义。你能否为我们解释一下你选择这种实现方式的原因?

Simon:这里的诀窍在于所生成的代码实现的功能只是一些繁琐的样板代码,这些生成代码的结构与你“手写”这些代码的结果是相同的。goagen 尽了最大努力以试图遵循“尽量减少令人惊讶的部分”的原则。你甚至可以说生成的最终代码看起来更“标准”(并且更高效)。举例来说,它减轻了对反射的依赖,否则的话,实现相同的功能可能要写上几千行代码。我们可以以客户端的 Go 包为例,你恐怕很难想到它居然是自动生成的。好吧,或许有些本地变量的命名看起来有点古怪,这可能会使你查觉到真相 :)

goa 的代码生成还有一个十分重要的特点,即所生成的代码始终处于一个不同的包中,而无需进行手动修改,从而清晰地区分了用户代码与生成的代码。goagen 将始终重新生成整个包,因此不可能出现用户代码与生成代码相混合的情况。这里有一种例外情况,即 goagen 可以在编码的起始阶段生成一种一次性的脚手架代码。

最后,goagen 只会生成必要的代码,所生成的代码将使用 goa 包实现各种通用的功能,例如日志记录、错误处理等等。它提供了一种优秀的方式对生成代码的行为进行自定义,而无需进行手动修改。举例来说,你可以实现一种自定义的服务错误处理逻辑,并且让所有生成代码自动调用这段自定义逻辑。你可以将这种生成代码想象为一种 goa 包的“插件”,并暴露相应的调节器以修改它的行为。

goagen 也支持插件系统,它实质上就是一种标准的 Go 包,其中包含了一个公开的 Generate 函数。由 Brian Ketelsen 所编写的 gorma 插件是对这一项目最早的贡献之一,它能够通过 API 设计中所描述的类型生成 gorm 模型。整个项目最令人惊讶的部分就在于通过代码(以及其他功能)生成所带来的各种可能性。在我看来,这一设想已经很明显地在 Go 语言中得到了很好的表现。

InfoQ:如果 InfoQ 的读者有兴趣加入“goa”项目,或是为其贡献代码,最好的途径是什么?

Simon:在 GitHub 库上的 wiki 中包括一份路线图的文档,其中可以找到许多建议,但这些仅仅是建议而已。这一项目最值得赞扬的一点在于它在社区中得到了快速的应用,而且在我所没有考虑到的方面也得到了许多代码贡献。goa 依然是一个很新的构架,整个项目的发展方向存在于许多可能性。此外,在 gophers.slack.com 上还有一个活跃的#goa slack 频道。因此,建议大家去访问 GitHub 库、加入 slack 频道,并且开始尝试!

本项目确实有一个地方或许需要大家的帮助:它需要一个 logo!它的网站页面可能也需要动一下整形手术 ;)

InfoQ:Raphael,感谢你参加今日的访谈。对于 InfoQ 的读者,你还有什么内容想同大家分享的吗?

Simon:感谢你的邀请!我推荐所有希望创建 API 的读者们去尝试一下 goa,我真的相信它能够帮助你们更高效地打造服务。微服务风格的架构如今已经快速地成长为事实上的标准,这使得设计优秀的 API 这一任务显得更为关键,而优秀的工具能够起到极大的作用。随着 goa 的使用率不断增长,我对于它的发展充满期待,并且迫不及待地想看到用户能够通过它实现哪些功能。

如果想了解有关 goa 微服务框架的更多信息,可以阅读 Gopher Academy 博客上的“ goa: Untangling Microservices ”这篇帖子,并访问 goa 的 GitHub 库

查看英文原文: Defining, Reviewing and Implementing Service APIs with “goa”, a Go-based Microservice Framework

2016-01-05 18:0010869
用户头像

发布了 428 篇内容, 共 177.5 次阅读, 收获喜欢 38 次。

关注

评论 1 条评论

发布
用户头像
dubbo-go
2020-11-20 01:37
回复
没有更多了
发现更多内容

一篇不太一样的RxJava介绍,2021年Android开发者跳槽指南

android 程序员 移动开发

一篇文带你了解程序员的生存环境到底有多难!,android开发案例教程与项目实战

android 程序员 移动开发

一篇文章教你搞清楚——Kotlin-进阶---不变型,android开发框架mvp

android 程序员 移动开发

三年开发经验,从小厂离职后,我凭什么拿到了阿里,作为一个Android开发者

android 程序员 移动开发

三年备战阿里面试功亏一篑,失败是成功他妈,最终拼下美团Android开发

android 程序员 移动开发

三面字节跳动被虐得“体无完肤”,为什么spring能最好地改变Android

android 程序员 移动开发

百万大数据 5 期 - BSM -02 课作业

Clarke

不愧是阿里技术官,Android-Framework的精髓全写在这本“限量笔记(1)

android 程序员 移动开发

不愧是阿里技术官,Android-Framework的精髓全写在这本“限量笔记

android 程序员 移动开发

一直认为Android不好找工作的同学,你的问题在这里!(1)

android 程序员 移动开发

构筑“数据连接器”,腾讯云大数据推出“开源开放”战略

科技热闻

一起来玩Weex,kotlin操作符重载

android 程序员 移动开发

实用函数式 Java (PFJ)简介

码语者

Java

三次失力美团Android 开发岗后,时隔一年终于成功拿下offer

android 程序员 移动开发

不学了,不学了,不学Android了,当上项目经理才知道

android 程序员 移动开发

一键登录了解一下?,揭秘

android 程序员 移动开发

一键调用,Get Android 实现视频连麦直播的核心原理,kotlin常用高阶函数

android 程序员 移动开发

三年Android开发却只有一年工作经验,是怎么收到offer的?

android 程序员 移动开发

三面阿里被挂,内推历经5面终获offer,我总结出了这些Android常用面试题和常见问题

android 程序员 移动开发

一直认为Android不好找工作的同学,你的问题在这里!,移动软件开发

android 程序员 移动开发

一篇文带你了解程序员的生存环境到底有多难!(1),Android端简单易用的SPI框架

android 程序员 移动开发

一篇文章搞懂Android 自定义viewgroup的难点,又是一年金九银十

android 程序员 移动开发

腾讯云李纲:国产数据库即将进入规模化阶段,未来五年助力1000家金融机构完成核心国产化

科技热闻

一篇文章教你读懂UI绘制流程我的Android重构之旅:框架篇

android 程序员 移动开发

一道腾讯面试官指点:组件之间的跳转和组件通信原理机制

android 程序员 移动开发

三月唯一一篇凉经奉上(Android 岗),成功跳槽阿里

android 程序员 移动开发

一篇文章教你搞定内存泄漏与排查流程——安卓性能优化,20道高频面试题(含答案)

android 程序员 移动开发

三年 Android 开发的技术人生,浅谈自身面试的感悟,华为架构师深入讲解Android开发

android 程序员 移动开发

三年磨一剑,这一次的金三银四打算离职的我准备好了,androidrom开发前景

android 程序员 移动开发

不妨借一步说话,你想知道的关于设计模式的种种,移动智能终端的发展趋势

android 程序员 移动开发

一线大厂大型APP性能优化系列-自定义启动器(三),整理出Android逆向系列学习进阶视频

android 程序员 移动开发

通过基于Go的微服务框架goa,实现对服务API的定义、审查与实现_语言 & 开发_Daniel Bryant_InfoQ精选文章