AI 年度盘点与2025发展趋势展望,50+案例解析亮相AICon 了解详情
写点什么

通过基于 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:0010904
用户头像

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

关注

评论 1 条评论

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

干货!天翼云DPU技术解码

天翼云开发者社区

【中秋福利】大数据告诉你:今年中秋礼品这样选

前嗅大数据

大数据 数据分析 数据采集 中秋 互联网+

第二届SmartNIC&DPU技术创新峰会即将开幕,速来围观

天翼云开发者社区

Spring知识点讲解

喜羊羊

后端 9月月更

Baklib|提高企业知识管理水平的方法分享

Baklib

知识管理

手把手教你君正X2000开发板的OpenHarmony环境搭建

华为云开发者联盟

鸿蒙 后端 IoT 企业号九月金秋榜

技术解读:Dragonfly 基于 P2P 的智能镜像加速系统 | 龙蜥技术

OpenAnolis小助手

开源 dragonfly p2p 龙蜥技术 镜像加速

Baklib|在线帮助中心对企业来说有多重要?

Baklib

企业 在线帮助中心

中国IPv6“高速公路”,全面建成 IANA被管理权限移交 ,IP地址管理何去何从

郑州埃文科技

ipv6 ipv4 IANA

Dubbo Mesh - 从服务框架到统一服务控制平台

阿里巴巴云原生

阿里云 开源 微服务 云原生 dubbo

Baklib|提升团队效率,在线协同文档好在哪?

Baklib

团队效率 在线协同文档

iOS端如何实现微信分享链接与登陆

MobTech袤博科技

微信 iOS SDK

华为云WeLink助力平房区打造智慧政务办公

科技怪咖

如何在 Jenkins CI/CD 流水线中保护密钥?

SEAL安全

DevOps jenkins CI/CD 密钥管理 CI/CD管道

ebook下载 | 《企业高管IT战略指南——搭建微服务架构》

York

微服务 云原生 系统架构 数字化转型 应用现代化

超酷炫!天翼云亮相中国服贸会

天翼云开发者社区

校招前端面试题

夏天的味道123

JavaScript 前端

leetcode 101. Symmetric Tree 对称二叉树(简单)

okokabcd

LeetCode 算法与数据结构

设计模式的艺术 第六章抽象工厂设计模式练习(开发一款新的手机游戏软件,该软件能够支持IOS和Android等多个智能手机操作系统平台。针对不同手机操作系统,该游戏软件提供了不同的游戏操作控制类和游戏界面控制类,并提供相应的工厂类来封装这些类的初始化过程)

代廉洁

设计模式的艺术

大众CEO迪斯提前卸任,成败皆因软件

雨果

软件定义汽车

字节前端必会面试题

helloworld1024fd

JavaScript

科技创新突破算力瓶颈,云网融合引领数字未来!

天翼云开发者社区

Mybatis

喜羊羊

mybaits 9月月更

javaweb

喜羊羊

javaWeb 9月月更

广东省湛江市等保测评机构有几家?怎么做?

行云管家

等保 等级保护 等保测评 湛江

Android技术分享| 视频通话开发流程(二)

anyRTC开发者

android 音视频 移动开发 实时消息 呼叫邀请

借助 TCP 负载均衡和 Galera 集群扩展 MySQL

NGINX开源社区

MySQL nginx 负载均衡 TCP/IP

实战Elasticsearch6的join类型

程序员欣宸

elasticsearch 9月月更

2022年全年Java岗面试题总结+一线互联网大厂Java岗面经/面试题总结!

程序员小毕

Java 程序员 面试 程序人生 后端

BI 报表正逐渐成为技术债,真的吗?

Kyligence

数据分析 指标管理 BI 报表

什么是数据湖?全面解读数据湖与数据仓库的区别

雨果

数据中台 数据仓库 数据湖 DaaS数据即服务

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