Go Time: Golang, Software Engineering - Raphaël Simon谈goa:构建微服务的框架 封面

Raphaël Simon谈goa:构建微服务的框架

Raphaël Simon on goa, the Framework for Building Microservices

本集简介

深入探讨goa:一个基于设计的微服务框架,其DSL可为API生成地道的Go代码、Swagger文档及测试辅助工具。 参与讨论 Changelog++会员支持我们的工作,更贴近技术核心,并享受无广告体验。立即加入! 赞助商: Linode – 我们首选的云服务器。每月仅需5美元即可获得最快、最高效的SSD云服务器。使用优惠码changelog2017可享4个月免费服务! Fastly – 我们的带宽合作伙伴。Fastly提供快速、安全且可扩展的数字体验。超越传统内容分发网络,体验其强大的边缘云平台。 嘉宾: Raphaël Simon – GitHub, X Erik St. Martin – GitHub, X Carlisia Thompson – GitHub, LinkedIn, X Brian Ketelsen – GitHub, X 节目笔记: Raphael Simon简介 Twitter Github RightScale 讨论 Swagger Gophers Slack上的#goa频道 Abstractions大会 - 优惠码(立减50美元):gotime 博客文章:《goa:解构微服务》 有趣的Go项目与新闻 CLI - 用Go构建命令行应用的包 Netflix的Scott Mansfield的精彩文章 Brian长期关注的项目 – Shield Heka - 轻松实现数据收集与处理 Uber的快速、结构化、分级Go日志系统 自由软件星期五 Brian - Bitly的NSQ,一个实时分布式消息平台及GopherCon 2014上Matt Reiferson的演讲《Spray Some NSQ On It》(视频) Carlisia iTerm2 v2.9beta或更高版本 Raphael - rethinkdb - 实时网络的开源数据库 + 所有允许员工开发开源项目的公司 Erik - RocksDB - 用于快速存储的可嵌入持久键值存储 发现遗漏或错误?欢迎提交PR!

双语字幕

仅展示文本字幕,不包含中文音频;想边听边看,请使用 Bayt 播客 App。

Speaker 0

我是拉斐尔·西蒙,欢迎收听Go Time。

I'm Rafael Simon, and this is Go Time.

Speaker 1

Go Time是一档每周播出的播客,我们将讨论围绕Go编程语言、社区以及相关的一切有趣话题。

It's Go Time, a weekly podcast where we discuss interesting topics around the Go programming language, the community, and everything in between.

Speaker 1

如果你目前正在使用Go,或者希望学习Go,那么这档节目非常适合你。

If you currently write Go or aspire to, this is the show for you.

Speaker 1

好了,各位。

Alright, everybody.

Speaker 1

欢迎再次收听Go Time的另一期节目。

Welcome back for another episode of Go Time.

Speaker 1

这是第七期节目。

It is episode number seven.

Speaker 1

今天,我们邀请到了布莱恩·凯特尔森。

Today, we have Brian Kettleson here with us.

Speaker 1

打个招呼吧,布莱恩。

Say hello, Brian.

Speaker 1

你好。

Hello.

Speaker 1

还有卡莉莎·坎波斯也在这里。

And Carlisa Campos is also here.

Speaker 2

很高兴来到这里。

Glad to be here.

Speaker 2

大家好。

Hi, everybody.

Speaker 1

我们还有一位特别嘉宾拉斐尔·西蒙,他是生成API的框架Goa的创建者,布莱恩对此特别兴奋。

And we also have a special guest here with us, Rafael Simon, who is the creator of a framework called Goa for generating APIs, which Brian is particularly excited about.

Speaker 1

你好。

Hello.

Speaker 1

拉斐尔,能给我们简单介绍一下背景吗?

You wanna give us a little bit of background, Rafael?

Speaker 0

当然。

Sure.

Speaker 0

嗯。

Yeah.

Speaker 0

那我们先从我是谁开始吧。

So let's start with who am I.

Speaker 0

我是Ridescale的平台架构师。

So I'm a platform architect at Ridescale.

Speaker 0

Ridescale是一个云管理平台。

Ridescale is a cloud management platform.

Speaker 0

我已经在那里工作了将近八年。

I've been working there for almost eight years.

Speaker 0

我刚加入时,整个产品基本上就是一个单一的Rails应用。

When I started, whole product was basically a single raise app.

Speaker 0

从那以后,平台有了很大的发展。

And the platform has grown a lot since then.

Speaker 0

上次我统计时,生产环境中大约有52个不同的服务,运行在大约一千台虚拟机上。

And last time I counted, there were about 52 different services running in production, now running on about a thousand VM.

Speaker 0

所以我参与设计、开发和调试了其中很多服务。

So I've helped design, develop, and debug a lot of them.

Speaker 0

从这个单一的RAZ应用演变成这么多分布式服务的过程中,我们在设计API时遇到了很多痛苦。

And part of going from this single RAZ app to all those distributed services, we felt a lot of pain in having to design APIs the right way.

Speaker 0

我的意思是,能够设计出一致且可执行标准的API。

What I mean by that is being able to come up with APIs that are consistent and have standards that are enforceable.

Speaker 0

这样我们就能说:是的,这个API看起来不错,符合我们的标准,我们可以将其与其余服务集成。

So that we can come up and say, yep, that API looks good, it follows our standards and we'd be able to integrate that service with the rest of the fleet.

Speaker 0

正如你可能知道的,一旦API上线,就几乎不可能再更改了。

And as you probably know, once an API is alive, it's almost impossible to change it.

Speaker 0

一旦有客户开始使用它,或者你的内部服务依赖于它,那么这个API就将永远存在。

Once you have customers that start using it or once your internal services rely on it, then that API is going to be alive forever.

Speaker 0

因此,花时间正确设计它非常重要。

So it is very important that you spend the time designing it properly.

Speaker 0

当我们审视当时可用的解决方案时,发现几乎没有合适的工具。

And when we looked at what was available to do that, there just wasn t much.

Speaker 0

这里有一些工具,但没有一个让我们觉得足够用。

There were a few tools here and there, but nothing that we felt would be enough for us.

Speaker 0

所以我们当时创建了一个名为Praxis的框架,它是用Ruby编写的,允许你编写设计代码,然后框架在运行时利用这个设计。

So we ended up creating a framework at the time that Framework was in Ruby called Praxis that basically allowed you to write a design code and then framework would leverage a design at runtime.

Speaker 0

随着时间推移,Redscape逐渐转向了Go语言。

Fast moving forward, Redscape kind of shifted towards Go.

Speaker 0

我觉得可以试试在Go中做点什么。

And I thought it would be good to see if we could do something with that in Go.

Speaker 0

老实说,我最初并不确定这是否可能。

And to be honest, I wasn't sure initially that would be possible.

Speaker 0

于是我尝试了几种方法,真正做出一个看起来可能可行的东西,花了我大约一年时间。

So I played around with a few things, and it took me about a year really to come up with something that started to look like it may work.

Speaker 0

在那个研究阶段,有两个关键的突破时刻。

So there were two big moments in that kind of research phase.

Speaker 0

一个是意识到代码生成是实现设计与实现分离、同时确保设计被直接强制执行的完美方法。

One was the realization that cogeneration was the perfect approach for achieving the goal of keeping the design and implementation separate while making sure that the design is directly enforced.

Speaker 0

第二个认识是,设计应该用一种领域特定语言(DSL)来编写,以便用于描述 API 的语言使用正确的术语。

And the second realization was that the design should be written in a DSL so that the language used to describe the API use the right terms.

Speaker 0

你希望讨论的是资源、操作、响应和请求,而不必处理编程语言的底层构件。

You want to talk about resources, actions, responses, requests, and you don't want to have to deal with programming language artifacts.

Speaker 0

因此,这种 DSL 必须是 GODSL,这样它能被立即理解,同时在需要时仍能使用 GODSL 语言。

So that DSL would have to be a GODSL obviously so that it could be understood right away and also so that it's still possible to use the the GODSL language too when it's needed.

Speaker 0

所以,快进到一年半之后,我必须说,结果比我预期的好得多。

So fast forward, like, a year and a half, and and I have to say that the result turned out a lot better than I thought it would be.

Speaker 0

我认为这很大程度上要归功于 Go 语言。

And I think a lot of the credit goes to the go language.

Speaker 0

Go 语言提供了一种简单而强大的机制来创建这种 DSL。

The Go language provides very simple and powerful mechanism to create that DSL.

Speaker 0

它还具有非常好的代码分析支持,这是必不可少的,并且拥有非常优秀的代码生成包,特别是 template 包。

It also has very good code analysis support, which is essential, and very good cogeneration packages, the template package in particular.

Speaker 0

因此,所有这些因素结合在一起,我认为今天我们最终得到了一个非常有趣的东西。

So all of that put together, I think we end up today with something that is actually very interesting.

Speaker 0

我们已经在Driscale内部广泛使用Goa了。

And we've started using Goa fairly extensively here at Driscale.

Speaker 1

那太好了。

So that's great.

Speaker 1

所以,简单来说,从高层次来看。

So just kind of like a high level detail.

Speaker 1

Goa是一个框架,使用用Go编写的DSL来生成HTTP API。

So Goa is a framework for using a kind of DSL that's written in Go to generate HTTP APIs.

Speaker 0

是的。

Yep.

Speaker 0

没错。

Exactly.

Speaker 0

它从那个设计——也就是那个DSL,你可以把它看作是一系列包级函数的调用,这些函数是递归的。

And it, you know, it it from that design, from that that DSL, which is Go code with basically, the DSL, you can think of it as a lot of package level functions that you invoke and that are recursive.

Speaker 0

所以你会调用一个顶层函数,比如API,然后在其中嵌套其他函数调用,以定义API的每一个属性,比如标题、描述等。

So you call a top level function, let's say, call API, and you then embed other function calls in it where you define every single property of the API like the title or description etc.

Speaker 0

所以当你看它的时候,其实并不难看。

So when you look at it, it's actually not too ugly.

Speaker 0

你可以很好地理解它,并清楚地知道它想要做什么。

You can actually understand it very well and follow what it's trying to do.

Speaker 0

从这个设计来看,当你加载设计并启动包含该包的进程时,所有设计代码都存在于全局变量中,Go 运行时会为你自动运行这些代码,最终你会得到大量描述你 API 的内存数据结构。

And from that design what happens is when you load the design, when you start the process that has that package linked in, all design code lives in global viable, the go runtime takes care of running all of that for you and you end up with a lot of in memory data structures that describe your API.

Speaker 0

这些数据结构很简单,没什么特别的,就是普通的 Go 数据结构,你可以查看、检查并用它们生成几乎任何东西。

And those are, you know, simple, nothing special, go data structures that you can look at, inspect, and use to to generate pretty much anything.

Speaker 0

这非常不错,因为你从一种对人类来说易于使用的语言开始,最终得到的是从程序角度非常容易处理的数据结构。

So it's quite nice because you start from a language that is easy to use from a, you know, human point of view, and you end up with data structures that are very nice to handle from a programmatic point of view.

Speaker 0

因此,Goa 自带了一些内置的代码生成输出。

And so Goa comes with a few built in code generation outputs.

Speaker 0

一个是连接 HTTP 服务器与用户提供的处理函数的胶水代码。

One is the glue code that bridges the role of an HTTP server with the user provided handlers.

Speaker 0

这段代码会根据描述语言中的验证规则,处理传入请求的验证。

And that code takes care of validating the incoming requests according to the validation rules describing language.

Speaker 0

它还会构建方便的数据结构,用于访问请求状态和编写响应。

It also builds convenient data structures for accessing the request state and writing the response.

Speaker 0

因此,作为用户,你需要编写的代码非常少。

So you end up with code that you have to write as the user, which is very small.

Speaker 0

你不需要做通常必须做的所有验证,也不需要将请求主体绑定到某个数据结构。

You don't have to do all the validation that you usually have to do and you don't have to bind the request body to some data structure.

Speaker 0

所有这些都已经完成了。

All of that is done already.

Speaker 0

你最终会得到一个称为上下文数据结构的东西,这个数据结构以一种非常容易访问和使用的方式组织了所有内容。

You end up with what is called a context data structure and that data structure has everything laid out in a way that's very easy for you to access and consume.

Speaker 0

你的代码会非常简洁和清晰。

Your code end up very is very terse and very clean.

Speaker 0

Goa 自带的 GoaGen 工具(即代码生成工具)会生成一个客户端包和一个客户端工具。

The the GoaGen tool that comes with Goa, which is the cogeneration tool, generates a client package and a client tool.

Speaker 0

这也很方便,因为当你创建一个 API 时,其目的显然是让 API 被使用,而通常的情况是,每个使用该 API 的团队都会开发自己的客户端,结果这些客户端都会过时,并且彼此之间存在细微差异,各种问题逐渐出现,使得整个系统更难演进。

That's also been very neat because, you know, one issue is when you create an API obviously the point is for the API to be consumed and what tends to happen is that every team consuming the tool will develop their own client and you know they will all become out of date and they will all have small discrepancies and and things start creeping up, which make the whole thing more difficult to evolve.

Speaker 0

因此,自动生成这些内容意味着提供 API 的团队也会提供客户端,所有人都使用这一个客户端。

And so having that being generated automatically means that the team that provides the API also provides the client and everybody uses that one client.

Speaker 0

这使得一切保持一致,并帮助其他团队使用该 API。

So it makes everything consistent and helps other teams consume the API.

Speaker 0

GoAgent 还会生成 Swagger 和 JSON 模式形式的文档,这样你随时可以将设计分享给不熟悉 GoAgent SL 的其他人,也可以在 API 上线运行后用它来记录 API。

And GoAgent also generates documentation in the form of a Swagger and JSON schema so that you can at any point in time share the design to other people that may not be familiar with the GoAgent SL and you can use it also to document the API once it's in once it's running production.

Speaker 0

所有这些都为开发 API 提供了一种非常出色且高效的方式。

So all of that makes for a very nice way of developing APIs and very efficient way of doing it.

Speaker 3

我有两个评论。

So I have I have two comments.

Speaker 3

我在去年十月或十一月发现了 Goa,当我第一次看到 Goa 时,有两件事立刻引起了我的注意。

I found Goa in October, November, I guess, of last year, and two things struck me immediately when I saw Goa.

Speaker 3

第一点是,生成的代码看起来像是手写的。

The first was that the generated code looked handwritten.

Speaker 3

我必须称赞你们这一点,因为对我来说,这个项目最令人印象深刻的部分就是,我之前见过的所有代码生成工具生成的代码都明显是自动生成的,而且不符合语言习惯。

And I have to commend you for that because for me, that was the most impressive part of the project was that, all other code generation facilities I've seen before, it's really clear that it's it's generated code, and it doesn't feel idiomatic.

Speaker 3

它看起来不像 Go 代码。

It doesn't feel like Go.

Speaker 3

它感觉像是有人生成的 Go 代码。

It feels like somebody generated some Go code.

Speaker 3

所以 Goa 生成的代码看起来如此像手写,这让我非常印象深刻。

So having that generated code in Goa looks so handwritten, was very impressive for me.

Speaker 0

谢谢。

Well, thank you.

Speaker 0

是的。

Yeah.

Speaker 0

我的意思是,这确实是设计目标之一。

I mean, that was definitely a design goal.

Speaker 0

你知道的?

You know?

Speaker 0

当我刚开始做 Goa 时,我并不是害怕,但有点担心 Go 社区会如何接受,因为我知道 Go 程序员虽然不挑剔,但他们希望 Go 代码看起来很地道。

I was when I started GOA, I was a little bit not afraid, but I was a little bit worried about the the reception that the Go community would have because I know that the Go programmers are very not picky, but they like the Go code to be dramatic.

Speaker 0

他们喜欢某种特定的方式。

They like a certain way.

Speaker 0

我不确定。

I don't know.

Speaker 0

他们希望代码看起来是某种样子,行为也是某种样子。

They like the code to look a certain way and and behave a certain way.

Speaker 0

所以我不希望通用代码成为问题,基本上是这样。

And so I wanted I I didn't want the generic code to be an issue, basically.

Speaker 0

我希望这根本不是问题。

I wanted that to be a nonissue.

Speaker 0

我希望人们看了之后会说,嗯。

I wanted people to look at it and say, yeah.

Speaker 0

好吧。

Okay.

Speaker 0

看起来足够好了。

It looks good enough.

Speaker 0

我不必这么做。

I don't have to.

Speaker 0

这并不糟糕。

It's not terrible.

Speaker 0

因此,我确实努力付出一些精力,让这成为Goa被采用时的一个非问题。

And so I definitely try to put some efforts to make that a non issue for the adoption of Goa.

Speaker 0

是的。

Yep.

Speaker 1

现在谈到符合Go语言习惯的风格以及社区的接受度,这个DSL本身的接受情况如何?

Now speaking of the kind of idiomatic go and reception from the community, what's the reception like for the actual DSL itself?

Speaker 1

因为我看过生成的代码,我认为它非常符合Go语言的习惯。

Because I've seen the generated code, which I think is highly idiomatic.

Speaker 1

但我不确定这个DSL本身是否也是如此。

But I don't know whether the DSL is so much.

Speaker 1

你经常收到这方面的反馈吗?还是人们对此相当适应?

Do you get a lot of slack about that, or are people pretty comfortable

Speaker 0

吗?

with that?

Speaker 0

在仓库和GitHub上,有一些评论说人们试图让DSL看起来更像Go,但我总是坚持一个明确的立场:这并不是Go。

There's been a few comments on the on the repo and GitHub of people trying to make it look more more like Go, but then I'm always very I kind of have a hard line saying this is not Go.

Speaker 0

这是一个DSL。

It's a DSL.

Speaker 0

这是一种不同的语言。

It's a different language.

Speaker 0

它是用Go实现的,但不是Go。

It's implemented in Go, but it's not Go.

Speaker 0

所以,例如,使用DSL时你必须做的一件事就是使用点导入。

So for example, one thing that you you sort of have to do when you use DSL is use dot imports.

Speaker 0

对吧?

Right?

Speaker 0

但很多人不喜欢这一点。

And a lot of people don't like that.

Speaker 0

我同意。

And I agree.

Speaker 0

我也觉得导入这种方式不太好。

I don't think that the imports are good either.

Speaker 0

我认为如果你在谷歌工作,就不应该使用它们,而且Go语言中其他地方也没用过。

I think if you're at Google, you shouldn't use them and nothing else in in Goa uses that.

Speaker 0

但为了实现DSL的目的,这样做能让整个东西变得更优雅,感觉更自然。

But for the purpose of using of implementing a DSL, that ends up being making the whole thing a lot nicer, feel a lot more natural.

Speaker 0

因此确实有一些反对声音,但我的回应是:这根本就不是Go,我也没打算让DSL变成地道的Go代码,因为它根本就不是Go。

And so there is a little bit of that pushback, but then my response is, well, this is not go, and I'm not trying I'm not trying for DSL to be idiomatic Go because it's not Go in the first place.

Speaker 0

如果你仔细想想,这个DSL的一些目标输出是文档。

And if you think about it, you know, some of the target outputs for the DSL is documentation.

Speaker 0

此外,你还可以从这个DSL生成一个JavaScript客户端。

There's also a JavaScript client that you can generate from that DSL.

Speaker 0

未来,还可以编写插件来生成其他语言的客户端。

And in the future, there can be a plugin written to generate clients in other languages.

Speaker 0

所以这个语言必须是中立的,对吧?

And so the language has to be agnostic, right?

Speaker 0

它必须独立于任何它生成的目标,当然,Go 是主要目标,但这个语言仍应尽量保持中立。

It has to remain independent of any target that it generates and sure, Go is the main target for sure, but still the language should try to remain as agnostic as possible.

Speaker 1

对。

Right.

Speaker 1

所以人们需要更好地分开来看,对吧?

So people just need to disconnect a little better, right?

Speaker 1

这有点像 gRPC,对吧?

It's kind of like gRPC, right?

Speaker 1

这个 DSL 本质上就是 protobufs。

You the the DSL is essentially the protobufs.

Speaker 1

对吧?

Right?

Speaker 1

然后生成器从那里生成代码。

And then the generator generates from that.

Speaker 1

你的恰好就是 Yep。

Yours just happens to be Yep.

Speaker 1

所以是的。

So yeah.

Speaker 0

嗯。

Yep.

Speaker 0

是的。

Yeah.

Speaker 0

我觉得就像,如果你写 Swagger,那它和你的编程语言就完全不一样了。

I see it's like, you know, if you write Swagger, then, yeah, it's completely different from your programming language.

Speaker 0

是同一个想法。

It's the same idea.

Speaker 0

嗯。

Yep.

Speaker 3

这让我想到了关于 Goa 的第二点,那就是 DSL 的易用性。

Well, leads me to the the second thing that I noticed about Goa, which was the approachability of the DSL.

Speaker 3

我以前见过很多DSL,因为我是前Ruby开发者,我们在Ruby中做的每件事在某种程度上都是一个DSL。

And I've seen many DSLs in the past, you know, being a a former Ruby developer, it's, everything we did in Ruby was a DSL in one way or another.

Speaker 3

所以看到Go中一个易懂、可理解的DSL让我感到非常惊讶。

So seeing a DSL in Go that was approachable and understandable was really surprising for me.

Speaker 3

我见过那些测试框架,是哪一个来着?

Had seen the, test frameworks, which one is it?

Speaker 3

Ginkgo、GoMega,其中一个

Ginkgo, GoMega, one

Speaker 0

这些

of those

Speaker 3

它们使用了类似的方法。

that uses a similar approach.

Speaker 3

但直到我实际使用Goa,才真正理解了它,我非常欣赏Goa中DSL的可读性。

And it still just didn't really click with me until I played with Goa, and I really enjoyed the readability factor of the DSL in Goa.

Speaker 0

谢谢。

Thank you.

Speaker 0

是的。

Yeah.

Speaker 0

花了好长时间才搞定。

That took a while to get right.

Speaker 0

有趣的是,你提到了Ginkgo和Gomega,它们确实是Goa DSL的重要灵感来源。

And actually, it's funny you mentioned Ginkgo and Gomega because they were definitely big inspiration for for the Goa DSL.

Speaker 0

你知道,我尝试过不同的迭代版本。

You know, I went through different iterations.

Speaker 0

其中一个版本我用的是字面量数据结构来定义DSL。

One iteration I was using literal data structures to define a DSL.

Speaker 0

那太丑了。

It was ugly.

Speaker 0

我的意思是,非常难看。

I mean, it was very ugly.

Speaker 0

当我看到把一个无名函数作为参数这个技巧时,我才真正明白了。

And I think it clicked once I I saw the trick of basically having an an innumous function being an argument.

Speaker 0

对吧?

Right?

Speaker 0

这确实是关键所在。

That's really the big the trick.

Speaker 0

一旦你明白了这一点,一切就都顺理成章了。

Once you see that, once you understand that, then everything kind of falls together.

Speaker 0

然后就可以轻松地嵌入这些函数调用,让它看起来就像一连串的指令,这很不错。

Then it's easy to sort of embed those function calls and make it look like it's just a series of instructions, which is is which is nice.

Speaker 0

嗯。

Yeah.

Speaker 0

但就是这个,嗯。

But that yeah.

Speaker 0

这花了好长时间。

That took a while.

Speaker 3

那么,Goa 的广泛采用中最让你惊讶的是什么?

So what has surprised you most about the explosion of Goa adoption?

Speaker 0

我对Goa社区以及你本人对Goa的热烈接纳感到非常非常印象深刻。

I was very, very impressed by how the Goa community and you especially really embraced Goa.

Speaker 0

我原本没想过,这只是一个个人研究性质的有趣项目,看看能发生什么。

I didn't think, you know, I was, it was more of a sort of personal research, interesting project, see what what could happen.

Speaker 0

同时也考虑到它可能在Ridescale被使用的潜力。

Also, with the potential of maybe being being used at Ridescale.

Speaker 0

但也就仅此而已了。

But that was about it.

Speaker 0

然后我猜你偶然发现了它,并开始在推特上分享。

And then I guess you stumbled on it and started tweeting about it.

Speaker 0

我写了一篇博客文章。

I wrote a blog post.

Speaker 0

是的。

Yeah.

Speaker 0

把我拉进了Slack频道。

Put me into the Slack channel.

Speaker 0

这真是太棒了。

And it's been awesome.

Speaker 0

我的意思是,如果没有这个社区,没有大家的反馈,Goa 绝不会成为今天的样子。

I mean, I think there's no way that Goa would be what it is today without that community, without all the input.

Speaker 0

你知道,这不仅仅是代码。

You know, the the it's not just code.

Speaker 0

还有想法、需求,以及大量的 bug 修复。

It's the ideas, the requirements, the the numerous bug fixes.

Speaker 0

我的意思是,每天早上醒来,看到一个 PR 修复了我写的 bug,这简直是最棒的事。

I mean, that that to me was like, waking up in the morning and seeing a PR where it fixes a bug I wrote, that's the best thing.

Speaker 0

我的意思是,没有什么比这更好的方式来开启一天了。

I mean, there's no better way to start a day.

Speaker 0

所以,是的,我非常印象深刻。

And so, yeah, I've been very impressed.

Speaker 0

我非常感激,这真的太棒了。

I'm very grateful, and it it's been it's been awesome.

Speaker 3

因此,我们正好谈谈我写的那篇博客文章,因为在这个节目中,我们有一个习惯,就是在每期节目的结尾讨论我们试图推广的‘自由软件星期五’运动。

So it's it's only appropriate that we talk about that blog post that I wrote because on this show, we have a habit, at the end of every show talking about the Free Software Friday movement that we're we're trying to portray here.

Speaker 3

而那篇博客文章是在十一月写的,我想应该是十一月,当时我提到自己偶然发现了Goa,觉得它简直太棒了。

And and that was the blog post in, I wanna say it was in November where I mentioned that I had stumbled across Goa and I thought it was just an amazing thing.

Speaker 3

我还谈到了如何与开源程序员交流,感谢他们的工作,并告诉他们你欣赏他们的付出。

And and I was talking about ways that you could talk to open source programmers and thank them for the work that they do and and tell them that you appreciate it.

Speaker 3

我想我甚至向你提过这个建议。

I think I actually even proposed to you.

Speaker 3

我不太确定。

I'm not sure.

Speaker 3

哦,我提过。

Oh, I did.

Speaker 3

是的。

Yeah.

Speaker 3

在2015年11月17日。

On on seventeen November two thousand fifteen.

Speaker 3

是的。

Yeah.

Speaker 3

我想娶写Goa的那个人。

I think I wanna marry the guy who wrote Goa.

Speaker 3

如果这让你感到任何不适,我必须向你道歉。

So I I have to apologize if that made you uncomfortable in any way.

Speaker 0

不。

No.

Speaker 0

这让我笑了。

That that made me laugh.

Speaker 0

这让我不得不找回我丢失的Twitter密码。

That made me have to retrieve my lost Twitter password.

Speaker 0

实际上,是的。

Actually, I yeah.

Speaker 0

当时我没在Twitter上,是我的一位同事看到了那条推文并告诉了我。

I wasn't on Twitter at the time, and it's a colleague of mine that saw that saw the tweet and told me about it.

Speaker 0

他们还笑得很开心。

And and they had a good laugh.

Speaker 0

我觉得这确实是,呃。

And I think it's it's yeah.

Speaker 0

这很棒。

It's been great.

Speaker 0

我真的非常感谢你们一直以来对Goa的支持。

I think it's I really appreciate all the support that that you've been giving Goa.

Speaker 0

而且我觉得,如果没有这些支持以及现在参与Goa开发的所有人,Goa也不会有今天的样子。

And I think, again, Goa wouldn't be, what it is today without all of that support and all the people now participating into the development of it.

Speaker 1

我知道这可能是几个月前的事了,但你当时进行了一次重构,对吧?为了支持可插拔架构,创建一些插件,因为我知道Brian后来确实写了一个用于ORM集成的插件。

And I know it was probably a few months ago, but you went through a refactoring, right, to kind of support Pluggable, to create kind of plug ins for stuff, because I know Brian ended up going through and creating a plug in for ORM integration.

Speaker 0

是的。

Yeah.

Speaker 0

我觉得Goa可能让Brian连续重写了同一个东西七遍什么的。

I think Goa may have caused Brian to kind of rewrite the same thing seven times in a row or something like that.

Speaker 0

抱歉啊。

So sorry about that.

Speaker 0

但没错,我当时主要是想在Brian开发那个大型插件的同时,让插件能够被添加到Goa中。

But yeah, I mean, it was basically an exercise of trying to make it possible for plugins to be added to Goa at the same time that the big plugin that Brian was developing was being developed.

Speaker 0

Brian写了一个叫Goma的出色插件,允许你用DSL定义模型。

Brian wrote this amazing plugin called Goma, which allows you to define models in DSL.

Speaker 0

现在你不仅可以定义API的结构,还可以定义数据库模型,Goma会根据这些定义生成代码,从请求体中实例化这些模型,并从模型生成响应体。

Now you can not only define your API shapes but you can also define the database models and from that Gourma generates code that will instantiate those models from request bodies and then create response bodies from the model.

Speaker 0

这让你能在几分钟内快速构建一个完整的全栈应用。

It makes it very easy to have a full stack kind of app in a few minutes.

Speaker 0

太棒了。

It's awesome.

Speaker 0

但没错,我当时正在努力让插件在Goa中正常工作,而Brian同时在开发Goma。

But yeah, I was working on on trying to make plug ins work in Goa in the same times that Brian was working on Goma.

Speaker 0

所以,你知道的,我可能让Goma崩溃了大概两百次。

And so, you know, I must have brought on go broken Goma maybe 200 times.

Speaker 0

我不知道。

I I don't know.

Speaker 0

差不多就是这样。

Something like that.

Speaker 3

不过,这个过程确实很有趣。

It was a sure fun process, though.

Speaker 3

没关系。

It's okay.

Speaker 0

嗯。

Yeah.

Speaker 0

嗯。

Yeah.

Speaker 0

嗯。

Yeah.

Speaker 0

我觉得,最终的结果还不错。

And I think, you know, the end result is is is nice.

Speaker 0

我觉得,你知道,现在任何为Goa编写插件的人都得感谢你。

I think, you know, I think anybody that now writes a plug in for Goa has to thank you.

Speaker 0

我觉得,是的,就是这样。

I think I think that's the yeah.

Speaker 0

这应该是条规矩。

That should be the rule.

Speaker 3

那么,你见过的最令人惊讶的插件是什么?或者对Goa最令人惊讶的贡献是什么?

So what's been the most surprising plug in that you've seen or or the most surprising contribution to Goa?

Speaker 0

嗯,我觉得GoaMar绝对名列前茅。

Well, I think GoaMar is definitely up there.

Speaker 0

你知道,一旦你仔细想想,这确实是一个非常重要的使用场景。

You know, it's it was clearly once you think about it, it's a use case that's that's really important.

Speaker 0

我只是没想到这一点。

I just hadn't thought about it.

Speaker 0

你知道吗?

You know?

Speaker 0

而且一旦你想到,哦,对了。

And and once you think, oh, yeah.

Speaker 0

显然,在获取请求负载后,你需要做的下一件事就是将其存储起来。

Obviously, the next thing you need you need to do after you get your request payload is to store it.

Speaker 0

嗯,是的,你得和某个数据库交互,而且没错,你可以生成代码来实现这一点。

Well, yeah, you're gonna need to talk to some database and and, yeah, you could generate code to do that.

Speaker 0

所以我认为这一直非常有趣,因为我之前没想到,这确实很有道理,而且我觉得非常有用。

So I think I think that has been, you know, very interesting because I hadn't thought about it, and it it it just makes a lot of sense, and I think it's very useful.

Speaker 1

所以我想要详细讨论实际的DSL有点困难,因为这全是音频形式的。

So I I guess it's kinda hard to go into detail about the actual DSL itself because this is all audio based.

Speaker 1

我的意思是,如果我们愿意,可以在各自的白板上画出来,但我觉得这样对听众帮助不大。

I mean, we could draw stuff on our own individual whiteboards if we wanted to, but I don't think somehow that's gonna help the listeners.

Speaker 1

不过,我想谈的一件事是,并不是每个人都熟悉代码生成。

So one thing I would like to talk about though is not everybody's kind of familiar with code generation.

Speaker 1

所以我想,当人们第一次听到这个想法时,经常会出现的一个问题是:你怎么维护生成的代码,对吧?

So I guess one thought process that constantly comes across people when they first hear the idea is how do you maintain generated code, right?

Speaker 1

比如,如果你要修改它并需要重新生成,你会覆盖掉你所有的东西吗?

Like if you were to modify it and you need to regenerate, are you wiping over all the top of your stuff?

Speaker 1

所以我很想听听你解释一下,对于已经生成的代码,你们的维护模型是怎样的。

So I'd love to kind of hear you explain kind of like what the model is for maintaining your code that's been generated.

Speaker 1

如果我有了 Goa 的新版本,想利用一些新功能或插件,那我之前为这个 API 手动编写的代码会怎样呢?

If I've got a new version of Goa and wanted to take advantage of some new features or plugins, what does that look like for the code that I had to manually write as part of that API?

Speaker 0

对。

Right.

Speaker 0

所以主要的想法是你不需要这样做。

So so the the main idea is you don't.

Speaker 0

你不需要维护通用代码。

You do not maintain generic code.

Speaker 0

基本上,通用代码会生成在它自己的包里,而且这些代码是廉价的。

Basically, you know, the generic code is is generated in its own package, and you it's cheap code.

Speaker 0

你不需要维护它。

You don't have to maintain it.

Speaker 0

你不需要测试它。

You don't have to test it.

Speaker 0

你也不需要真正了解它的内部原理。

You don't have to really know the internals of it.

Speaker 0

你可以查看它们,希望它们是易懂的,但你其实不必看。

You're welcome to look at them, and, hopefully, it's understandable, but you don't have to.

Speaker 0

你只需要关心它为你提供了什么,以及它如何与你的代码交互。

All you care about is what it provides to you and how it interfaces with your code.

Speaker 0

对吧?

Right?

Speaker 0

因此,Goa 的代码生成原则之一是用户代码和生成代码绝不混合。

So one of the the kind of code generation principle behind Goa is that user code and generated code never mix.

Speaker 0

它们之间有一个非常清晰的接口,一个明确的 Go 接口。

And there is a very clear interface, an explicit I mean, mean, a Go interface.

Speaker 0

对吧?

Right?

Speaker 0

这两者之间有着非常明确的接口。

It's it's it's a very explicit interface between the two.

Speaker 0

我的意思是,这不止一个。

I mean, it's not just one.

Speaker 0

而是多个。

It's multiple.

Speaker 0

但核心理念是,生成的代码和用户代码之间有着清晰的接口。

But the idea is that you have interfaces that are clear between the generated code and the user code.

Speaker 0

如果你重新生成代码,你根本不需要在意。

And if you regenerate your code, you shouldn't care.

Speaker 0

我的意思是,基本上,如果你改变了设计,比如在请求负载中添加了一个新字段,重新生成代码后,你的契约中就会多出一个字段,你可以直接使用它,仅此而已。

I mean, basically, idea is if you change your design and you add let's say, add a new field to a request payload, you regenerate your code, all that means is now your contact subject has a new field and you can use it and that's it.

Speaker 0

你不需要担心其他任何事情。

You don't have to worry about anything else.

Speaker 0

当然,有时接口可能会出现断裂。

Obviously, there are cases where the interface may break.

Speaker 0

它们可能在不同工具之间有所变化,但在这种情况下,应该清晰明了。

They may change between different tools, but in that case, it should be clear.

Speaker 0

你应该是在从1.0版本平滑过渡到2.0版本,而不是随意更改。

It should be you're moving from, you know, one point o to two point o, and and you're doing that consortuously.

Speaker 0

这不应该是某种副作用。

It shouldn't be something that is a side effect.

Speaker 0

因此,我一直非常谨慎,因为过去我有过CORBA、IDL、MIDL的经验。

So I've been very careful about that because in the past, I've had experience with, you know, CORBA, IDL, MIDL,

Speaker 1

而且它

and it

Speaker 0

每当生成的代码与用户代码混合时,总是非常痛苦。

was always very painful whenever generated code mixed with user code.

Speaker 0

那么现在你该怎么办?

Because now what do you do?

Speaker 0

你是要测试整个系统吗?

Do you test the whole thing?

Speaker 0

那么,你现在拥有生成的代码吗?

So do you now own the generated code?

Speaker 0

对吧?

Right?

Speaker 0

你需要测试它来维护它吗?

Do do you need to test it to maintain it?

Speaker 0

然后你就陷入了生命周期的问题。

And then you are running to the issues of of life cycle.

Speaker 0

当你更改源代码时,你就需要修改那部分代码。

When you change the source, then you need to change that code.

Speaker 0

所以我知道,有时一些MIDI生成器会在你的文件注释中添加标记。

So I know sometimes some, like, some MIDI generators would put markers in comments in your file.

Speaker 0

对吧?

Right?

Speaker 0

然后它们会找到这些标记,并在中间修改代码,而你不应该更改那些部分。

And then they would find those markers and change the code in between, and you were not supposed to change that.

Speaker 0

所以我真的想尽量避免遇到这些问题。

So was re I really wanted to try and avoid running into that those issues.

Speaker 0

因此,所有通用代码都放在一个不同的包中,你不需要修改它。

And so all the generic code goes into a different package, which you do not touch.

Speaker 0

实际上,你不能修改它,因为生成器每次都会清空整个目录。

Actually, you cannot touch it because the generator the cogenerator will wipe out the entire directory every time.

Speaker 0

所以你的代码不可能与生成的代码混在一起。

So you there's no way that your code is gonna mix with the generated code.

Speaker 0

而接口是一个 Go 接口。

And the interface is is is a Go interface.

Speaker 0

它是显式的,这就是你们双方交互的方式。

It's explicit, and that's how you both could interact.

Speaker 2

所以当你说到不必测试自动生成的代码时,其中一部分代码是控制器。

So when you say don't worry about testing the code that was auto generated, part of the code was the controllers.

Speaker 2

你是说你的工作流程是怎样的?

Are you saying so how is your workflow?

Speaker 2

那么,你会手动为集成、功能和噪声编写测试吗?

Do you then go and manually write tests for integration, for functionality and noise specifically?

Speaker 2

我不太喜欢专门测试控制器。

I'm not a huge fan of testing controllers in specific.

Speaker 2

我更倾向于测试集成。

I'm more a fan of testing integration.

Speaker 2

但你又是如何手动编写这些测试的呢?

But how do you then go and write it manually?

Speaker 0

GoAgent 生成的控制器是属于你的代码。

So the controllers that GoAgent generate are this is code that you own.

Speaker 0

GoAgent 生成的代码有两种类型。

So there's there's two kinds of code that GoAgent generates.

Speaker 0

其中大部分代码是位于不同包中的内容,你无需担心。

One is the vast majority of the code is things that are leaving different packages that you don't worry about.

Speaker 0

但还有一种是骨架代码,它只是帮助你快速上手的引导代码。

But then there's also this scaffolding code, which is kind of just a bootstrap code to help you get started.

Speaker 0

对吧?

Right?

Speaker 0

它不是那种你会随着时间反复重新生成的东西。

It s not something that you re going to regenerate over time.

Speaker 0

它是一次性的工作,能帮助你快速搭建服务,立即进行测试和体验。

It s something that you do once and it helps you quickly compile your service and be able to test it and play with it right away.

Speaker 0

因此,对于这部分代码,它属于你。

And so for that code, that code belongs to you.

Speaker 0

这部分代码你需要测试和维护,就像维护你自己的代码一样。

That code you test it and you maintain it like your code.

Speaker 0

而且下次你使用 GoHN 时,它不会覆盖这些文件。

And actually next time you're on GoHN, it won't overwrite those files.

Speaker 0

这些文件位于主包中。

And those files live in the main package.

Speaker 0

所以控制器位于主包中,你需要测试它、拥有它。

So the controller lives in the main package and and you test that you own that.

Speaker 0

默认在名为 app 的包中生成的底层处理程序,这些是你不需要维护、不需要担心的。

The the low level handlers that get generated in by default in the package called app, those those those are the ones that I'm saying you don't have to maintain, you don't have to worry about.

Speaker 2

明白了。

Got it.

Speaker 2

另外,在准备这期节目时,我看了布莱恩·凯尔特森在坦帕的一场演讲。

And I wanted to say too, in prepping for this episode, I watched a talk that Brian Keltelson gave in Tampa.

Speaker 2

这简直太棒了。

And it's simply amazing.

Speaker 2

如果你还不了解 Goa 并且对此有任何兴趣,这场演讲时长一小时十五分钟,但绝对值得一看,因为他展示了 Goa 在 Gurma 中提供的功能,并且演示了代码。

If you have, if you don't know Goa and have any interest at all, the talk is at an hour fifteen, but it's so worth it because he, shows the functionalities that Goa provides in Gurma and that he shows codes.

Speaker 2

我几乎看完了整场演讲,从中对 Goa 的功能有了非常清晰的理解。

And pretty much I watched the whole talk and I came away with a very good sense that I understood what Goa does.

Speaker 2

我觉得它用起来非常简单。

And I thought it was very simple to use.

Speaker 2

我还想到一点,我来自 RHELDS 背景,发现了很多相似之处。

Another thing that I thought was I come from a RHELDS background and I saw a lot of similarities.

Speaker 2

对我来说,这感觉完全可以作为 Rails 的替代方案,如果我想用 Go 开发后端应用或 API 应用的话。

To me, it felt like this could very much be an alternative to Rails if I wanted to do a backend app or an API app in Go.

Speaker 2

但不同的是,它并没有隐藏很多底层细节。

But except that it didn't abstract away a lot of the things.

Speaker 2

我能直接看到代码在做什么,一切都完全在我掌控之中,而不是仅仅调用一些我可能懂、也可能不懂的抽象封装。

I saw right there what the code was doing, and it was very much under my control, as opposed to just calling it abstractions that maybe I knew or maybe I didn't.

Speaker 0

是的,确实有一些相似之处,比如你有控制器和资源,这一点确实很类似。

Yeah, it's I mean, there's definitely some similarities in the way that you have controllers and you have resources and so that definitely is similar.

Speaker 0

我认为 GOA 还试图保持简单。

I think also one other thing that GOA is trying to do is stay simple.

Speaker 0

对吧?

Right?

Speaker 0

我们在这里大量使用了 Raise,而且我们的应用规模已经远远超出了 Raise 原本设计的用途。

So one other thing that that we've used Raise quite a bit here, and, you know, we've grown application probably way too big for what Raise was supposed to to be doing.

Speaker 0

因此,我们在一些插件上遇到了很多问题,而且在某个时候,我想我们使用的 gem 数量已经超过了一百个。

And so we felt a lot of pain with some of the plug ins and some of, you know, the at some point, I think we had, like, 100 more than a 100 gems we're using.

Speaker 0

因此,到了这个时候,要理解整个请求流程几乎变得不可能。

And so at this point, it becomes almost impossible to understand the request flow throughout.

Speaker 0

所以我认为 Go 正在努力保持简单,充分利用 Go 的优势。

And so something I'm I think Go is trying to do is to keep things simple, kind of get the best of Go.

Speaker 0

对吧?

Right?

Speaker 0

Go 的原则是创建简单、专注的工具,这些工具可以组合起来实现你想要的功能,同时兼顾实用性——你不必每次都从头重建一切。

The Go principles of of doing simple tools that do simple things and and can be composed together to achieve what you want and try to get those ideas and mix them with, at the same time, the practicality, right, of of doing something where you don't have to rebuild everything every time.

Speaker 0

所以我认为,这其实是两个略微对立的目标,但这种张力很好。

So that's that's I think that's a nice little it's kind of two goals that are a little bit opposed to each other, but it's a good tension.

Speaker 0

我认为 OA 正在努力在这两者之间取得平衡。

I think OA is trying trying to strike the balance between the two.

Speaker 2

是的。

Yeah.

Speaker 2

我的印象是,使用它非常简单,因为当你进入一个 Rails 应用时,上手非常容易。

My my impression was that it was very easy in the sense that when you jump into a Rails app, it's very easy to get going.

展开剩余字幕(还有 334 条)
Speaker 2

所以从这个角度来说,它很容易。

So it was easy in that sense.

Speaker 2

但它也很简单。

But it was also simple.

Speaker 2

这正是我想说的,你知道,在 Rails 中,我用了大量的抽象,也许我曾去看过 Rails 的源代码,知道它是什么东西。

And that's what I was trying to say, you know, in Rails, I'm using a lot of abstractions that maybe I went into the Rails source code and looked at it and I know what it is.

Speaker 2

但我可能并没有看过。

But probably I didn't.

Speaker 2

而使用 Goa 和 Gorma,我能直接看到一切。

And with using Goa and Gorma, I see everything right there.

Speaker 2

我能直接掌控正在发生的事情,而且它很简单。

I have direct control of what's going on, and it's simple.

Speaker 0

是的。

Yeah.

Speaker 0

这说得通。

That makes sense.

Speaker 0

我很高兴你这么说。

I'm happy you say that.

Speaker 0

我的意思是,这确实也是一个目标,就是尽量简化事物,隐藏连接Mercs等在生成代码中的大量复杂性。

I mean, that was definitely a goal too is trying to simplify things and kind of hide a lot of the complexity of hooking up, you know, the Mercs and so in the generated code.

Speaker 0

而用户需要实现的部分应该相当直接。

And then what you have to implement as the user should be fairly straightforward.

Speaker 0

基本上,你需要处理的数据结构就是你在设计中定义的那些,所以一切都应该非常可预期,而且使用起来相当简单。

Basically, the data structures you have to deal with are the ones that you define in your design, so it should all be very expected and and fairly simple to use.

Speaker 0

没错。

Yep.

Speaker 3

关于这一点,我有个小故事。

Now I have an anecdote about that.

Speaker 3

在Goa的Slack频道,也就是Gopher Slack里,我们称拉斐尔为教父。

In the the Goa Slack channel, in the Gopher Slack, we call Rafael the godfather.

Speaker 3

这是因为他对DSL的简洁性和用户体验有着极致的投入。

And that's and that's because of his extreme dedication to the simplicity of the DSL and the user experience.

Speaker 3

他不会让任何复杂化流程的事情溜过去。

He will not let anything get by that complicates the process.

Speaker 3

我真的非常欣赏这一点。

And and I really appreciate that.

Speaker 3

我认为,这种对用户体验和开发者体验的极致专注,正是Goa优于许多其他代码生成器的地方——其中一些我写过的工具简直糟糕透顶。

I think, having that laser sharp focus on user experience and developer experience is what makes Goa a great tool versus many of the other co generators, some of which I've written that suck.

Speaker 3

所以这一点很重要。

So that's important.

Speaker 3

每个项目都需要有这样的教父。

You have to have the godfather in every project.

Speaker 0

是的。

Yeah.

Speaker 0

尽量把所有这些……你知道的,把所有复杂性都隐藏在下面。

Try to hide all the, you know, keep all the complexity below.

Speaker 0

如果你想看,可以看,但你不必去处理它。

Can look at it if you want, but you don't have to deal with it.

Speaker 0

我觉得这是一个非常有趣的原理。

Think it's a very interesting principle.

Speaker 0

你面对的是一个大型团队中的各个层级的开发者,他们都必须使用你的工具。

You get developers of, like in a big team, you get developers of every level that need to use your tool.

Speaker 0

所以我认为你需要让它易于上手,让任何人都能充分利用它。

So I think you need to make it approachable so anybody can take advantage of it and leverage it as best as possible.

Speaker 0

你必须了解工具的工作原理,才能充分发挥它的优势。

You have to know how the tool works to take full advantage of it.

Speaker 0

我认为工具的职责就是确保你能以简单的方式使用它,所有复杂性都对你隐藏起来。

I think it should be it's the tool's job to make sure that you can use it in a way that's easy and all the complexities hidden from you.

Speaker 0

同时,如果你是更高级的用户,或者你很好奇想了解它是如何工作的,这些内容也不应该被完全隐藏。

At the same time, if you are a more advanced user or you are curious and you wanna see how it works, it shouldn't be hidden either.

Speaker 0

底层的结构也应该有良好的设计,等等。

And what's underneath should also be fairly nice design and blah blah blah.

Speaker 0

但你一开始并不需要接触所有内容。

But you shouldn't have to be exposed to the whole thing from the get go.

Speaker 1

过去几年中,另一个变得极其流行的是 Swagger,或者说是 API 规范。

So another thing that's kind of risen in extreme popularity over the past couple of years is Swagger, or doing API specifications.

Speaker 1

据我了解,Go 语言也会自动生成所有的 Swagger 规范,因此你使用这种 DSL 定义的任何内容都能免费获得 Swagger UI。

And as I understand it, Go also generates all the Swagger specs so that you get the the Swagger UI kind of for free for anything that you define in this DSL.

Speaker 0

是的。

Yeah.

Speaker 0

我的意思是,Swagger 确实是设计中抽象概念的重要灵感来源。

That's I mean, Swagger was definitely a big inspiration for the abstractions in the design.

Speaker 0

因此,Swagger 生成功能相当完整,这一点并非巧合——你能在 DSL 中表达的任何内容,也都能在 Swagger 中表达出来。

So there is no coincidence that, you know, it's the Swagger generation is is fairly complete in in the sense that you can express anything that you can express in Swagger in a DSL.

Speaker 0

实际上,最初的灵感来自 JSON Schema。

Actually, first the first inspiration was JSON Schema.

Speaker 0

我不知道你是否熟悉 Heroku 如何记录他们的 API,但他们使用一种递归的 JSON Schema 来描述他们所有的 API。

I don't know if you're familiar with how Heroku document their APIs, but they use JSON Schema, this kind of recursive JSON Schema to describe all of all of their APIs.

Speaker 0

因此,这成为了设计语言中抽象概念的最初灵感来源。

And so that was kind of the initial inspiration for abstractions in the design language.

Speaker 0

但后来发现,Swagger 也使用 JSON Schema 来描述他们所谓的路径对象。

But then it so happened that Swagger is also using JSON Schema for a lot of their representation of what they call the path object.

Speaker 0

因此,这种映射非常容易实现,而且显得很自然。

And so that mapping was very easy to do and it just was sort of natural.

Speaker 0

是的,我觉得这很棒,因为这意味着那些已经熟悉 Swagger 的人,已经习惯于思考 API 设计,会感到非常熟悉。

Yeah and I think it's great too because that means that people that already know Swagger are already used to thinking about design of APIs will feel right at home.

Speaker 0

他们只需要处理他们已经熟悉的相同抽象概念。

They will have to deal with the same abstractions that they already know.

Speaker 0

实际上,我认为一个有趣的方向或附加项目是,为 Goa 开发一个工具,它可以接收某个 Swagger 定义并生成 Goa 的 DSL——当然,Goa 本身已经可以反向生成 Swagger。

And actually I think an interesting project or add on that could be done with Goa is a tool that would take some swagger definition and generate so that the Goa DSL can of course go the other way around.

Speaker 0

如果你编写 Goa DSL,就能得到 Swagger。

If you ride the GoaDSL, you get Swagger.

Speaker 0

如果能从 Swagger 反向生成 Goa DSL,那也会很有趣,这样你就能利用 GoaGen 生成所有其他内容。

Would be also interesting if you had Swagger to be able to go to a GoaDSL because then you would be able to take advantage of GoaGen to generate all those other things.

Speaker 3

知道吗,他在分配这个

Know, he's assigning that

Speaker 1

到你的大脑。

to your brain.

Speaker 3

抱歉?

Pardon me?

Speaker 1

那是你的领带。

That's your tie.

Speaker 1

他把这个分配给你了。

He's assigning that to you.

Speaker 3

那是你的领带。

That's your tie.

Speaker 3

我刚才想说,如果你从一个Swagger规范开始,生成一个Goa DSL,然后Goa DSL再生成Swagger规范,你就可以让这个过程陷入无限循环。

I was just gonna say, if you started with a Swagger specification and you generated a Goa DSL, and then the Goa DSL generated a Swagger specification, you could set that thing into an endless loop.

Speaker 3

到最后,它就会成为图灵完备的。

And by the end of it, it would be Turing complete.

Speaker 0

是的。

Yes.

Speaker 0

实际上,看看Swagger随着时间的推移如何演变,是会退化还是怎样,会非常有趣。

It'd be actually very interesting to see how the Swagger evolves over time, whether it degrades or, you know.

Speaker 3

或者它是否会掌控世界并开始发射核武器

Or whether it takes over the world and starts launching I nuclear

Speaker 2

我想问拉斐尔一个问题。

have a question for Rafael.

Speaker 2

我觉得Goa的视图功能非常有趣。

The views aspect or feature of Goa, I thought it was super interesting.

Speaker 2

我记得以前做过一个Rails应用,它的API以RESTful资源的形式提供立方体数据,我们需要实现一些复杂的过滤器。

I remember working with a Rails app, an API that was serving cube data as RESTful resources, and we had to do some filters that were complicated.

Speaker 2

一旦我们找到了模式,就一直遵循这个模式。

Once we figured out a pattern, it was, we just followed the pattern.

Speaker 2

这有点简单。

It was sort of simple.

Speaker 2

但后来我因为使用Swagger文档工具而遇到了问题。

But then I ended up running with problems because we were using the Swagger documentation tool.

Speaker 2

Swagger 作为一个文档工具,不是用来设计 API,而是仅仅用来记录 API。

Swagger as a documentation tool, not necessarily to design the API, but just to document the API.

Speaker 2

因此,在我们实际操作和 Swagger 规范(无论我们使用的是哪个版本的规范)之间存在不匹配。

And so there was a mismatch there between what we were doing in between the specs, that Swagger, Swagger spec, whatever the spec version was that we were using.

Speaker 2

现在,关于 API 的查询参数和过滤功能,这就是 views 所做的吗?

Now, with query params and filtering features of an API, is that what the views does?

Speaker 2

也就是说,如果你有不同的过滤条件,我可以使用不同的 views 来表示它们吗?

Is that like if you have different filtering criteria, I can use different views to represent that?

Speaker 2

就是这样吗?

Is that what it is?

Speaker 0

是的,我的意思是,没错,这就是它的初衷。

Yeah, I mean, yeah, that's the idea.

Speaker 0

所以,核心想法是,一个资源可以用多种方式来表示,对吧?

So, you know, the idea is that a single resource may be represented in different ways, right?

Speaker 0

比如,你可能有一个只包含少数字段的索引视图,也可能有一个包含其他字段的详细视图,还可能有其他专门用途的视图。

You may have an index view for example that only has a few fields and you may have a detailed view that has other fields and you may have another view that is specialised in some other way.

Speaker 0

所以,你的想法是不应该每次都要重新定义一种不同的媒体类型。

And so the idea is that you shouldn't have to kind of redefine a different media type every time.

Speaker 0

因此,你只需定义一次媒体类型,列出该媒体类型的所有字段,然后定义不同的视图来表示这种媒体类型。

So you define your media type once, you list all the fields of the media type and then you define views, different ways of representing that media type.

Speaker 0

每个视图都可以定义媒体类型中已定义的任意字段。

And each view can define arbitrary fields that were defined in the media type.

Speaker 0

至于如何根据请求生成这些视图,那就由你来决定了。

Then how you produce those views from the request is already up to you.

Speaker 0

所以,如果你决定使用一个名为 view 的查询字符串参数,其值可以是 index 或 expanded,那就很好。

So if you decide that you want to use a query string parameter called view and the name can be either index or expanded, then great.

Speaker 0

这样做吧,在你的控制器和代码中,你基本上会根据查询字符串的值构建使用相应视图的响应。

Do that and in your controller and your code you basically build a response using the view that you wanted for value of the query string.

Speaker 0

所有这些也会被转换为生成的 Swagger 文档,表现为该操作的不同响应。

That all gets also translated into the swagger that gets generated as basically different responses for the action.

Speaker 0

因此,所有内容都得到了文档化,而且你还能获得无需每次重新定义所有这些不同媒体类型的额外好处。

So it's all documented and you get also the benefit of not having to redefine all those different media types every time.

Speaker 2

是的,这听起来太棒了。

Yeah, that sounds brilliant.

Speaker 2

我猜这也更容易记录。

And I bet it's a lot easier to document as well.

Speaker 0

是的,是的,我的意思是。

Yeah, yeah, I mean, is.

Speaker 0

而且我觉得人们本能地就能理解它,对吧?

And I think people have a sort of instinctive understanding of it, right?

Speaker 0

这很合理,对吧?

It makes sense, right?

Speaker 0

如果我想索引你,那就太好了。

If I want to index you, then great.

Speaker 0

不知道。

Don't know.

Speaker 0

这是同一个后端资源,只是表现方式不同而已。

It's the same backing resource, it's just different ways of representing it.

Speaker 0

所以我认为这并不是一个很复杂的抽象,它确实为DSL增添了很多内容。

So I don't think it's a very complicated abstraction, and it does add a lot to the to the to the DSL.

Speaker 1

是的。

Yeah.

Speaker 1

我同意这一点。

I like to make agree with that.

Speaker 1

那是什么?

What's that?

Speaker 3

我只是说,我完全同意这一点。

I I'm just saying I would completely agree with that.

Speaker 3

我喜欢这样的想法:视图用稍微不同的方式表示同一个资源,不同的使用场景并不意味着你需要写大量不同的代码。

I love the the idea of views having the same resource represented slightly differently for a different use case doesn't mean you should have to write a ton of different code.

Speaker 3

你只需用特定的视图来请求该资源。

You just ask for that resource with a specific view.

Speaker 2

嗯。

Mhmm.

Speaker 2

嗯。

Yep.

Speaker 1

所以我想确保我们留出一些时间进行一次轻松的对话,聊聊我们共同遇到的新闻、项目之类的事情。

So I'd like to make sure we have kind of time to do a a fireside chat, you know, talking about kind of news and and projects and stuff we've run across together.

Speaker 1

所以在我们离开 Goa 之前,我想听听你的看法:Goa 的下一步计划是什么?

So before we move on off of Goa, I'd just kinda like to hear from you, like, what's next for Goa?

Speaker 1

你打算在近期内添加哪些功能?

What kind of functionality are you looking to add here in the near future?

Speaker 0

有几件事,首先我要说明,Goa 还没有到 1.0 版本,所以近期的目标是完成 1.0,我们已经非常接近了。

So there are a couple of things that, first off I should say that Goa is not one point zero yet, so I think the near future is going to be finishing one point zero and we are very close.

Speaker 0

我认为合理的做法是完成我们已经开始的安全性示例,因为这一领域的复杂性可能比其他部分更高,因此提供良好的示例非常有意义。

What I think would make sense is to finish up the security examples that we've started because that's an area that can get a bit hairier than the other areas, so having good examples around that makes a lot of sense.

Speaker 0

所以完成这些示例,确保大家对它们都满意,然后我认为我们就可以冻结功能,发布 1.0 版本了,不管那具体意味着什么。

So finishing those examples, making sure everybody is happy with those, and then I think at that point we'd be ready to freeze and kind of ship one point zero, whatever that means.

Speaker 0

但我们的目标是让这个版本变得稳定。

But the idea is that then that is stable.

Speaker 0

所以如果你一直在等Goa稳定后再使用,现在时机到了。

So if you were waiting for Goa to be stable to use it, there you go.

Speaker 0

现在你可以开始使用了。

Now you can start using it.

Speaker 0

接下来我们谈谈Vina X2.0,目前我正在关注几个有趣的方向。

And now for moving on for Vina X2.0, I think there's a couple of interesting areas I'm looking at right now.

Speaker 0

一个是将Goa扩展到HTTP之外。

One is extending Goa beyond HTTP.

Speaker 0

特别是,我一直在研究gRPC。

So in particular, I've been looking at gRPC.

Speaker 0

这一直是大家频繁询问的领域,也是我们在Ridescale内部正在关注的方向。

I think it's an area that that have been asked a lot and it's also something we are looking at here at Ridescale.

Speaker 0

所以我想看看我们能在这里做些什么。

So I'd like to see what we can do there.

Speaker 0

这会很有趣,因为一些抽象概念并不完全匹配HTTP REST的抽象方式,所以我们得想出一些创新的解决方案,但我认为这是有道理的。

It's going to be interesting because some of the abstractions are not don't match exactly the kind of HTTP REST abstraction, so we're gonna have to come up with some interesting solutions there but I think it makes sense.

Speaker 0

另一个有趣的领域是让DSL引擎更具灵活性。

Another interesting space is making the DSL engine a bit more flexible.

Speaker 0

今天我们提到,可以编写插件,插件可以定义自己的DSL,或者定义自己的输出。

Today we've mentioned it's possible to write plug ins and plug ins can define their own DSL and or they can define their own output.

Speaker 0

但如果你想让一个插件的输出影响另一个插件或内置生成器的输出,就会变得困难一些。

But it's a bit more difficult if you want an output from one plugin to affect the output of another plugin or a built in generator.

Speaker 0

举个例子,假设你想编写一个安全插件。

So an example of that would be know, what if you wanted to write a a secure security plugin.

Speaker 0

对吧?

Right?

Speaker 0

然后你可以在API描述中加入一些DSL,比如:

And and there would be some DSL that you can put in your API description that says, hey.

Speaker 0

如果需要调用这个操作,就必须经过这个授权中间件。

If you need to call this action, then this is the authorization middle way that you need to go through.

Speaker 0

如果今天想实现这一点,会有点困难,因为你无法修改内置生成器为底层HTTP服务器胶合代码生成的输出。

If you wanted to do that today, it would be a bit difficult because you couldn't modify the output generated by the built in generator for the for the low level HTTP server glue.

Speaker 0

因此,我认为这是另一个值得探索的有趣方向,即让 Go 变得更加开放,让更多人能够为它贡献更多插件。

And so I think that's another interesting dimension to look at in terms of trying to make Go a bit more open and have have more people being able to contribute more plug ins to it.

Speaker 0

所以这也是我在思考的问题。

So that's this is also something I'm I'm thinking about.

Speaker 1

不。

No.

Speaker 1

这太棒了。

This is great.

Speaker 1

我的意思是,如果有人想持续关注或深入了解 Goa,goa.design 可能是最好的地方。

And I mean, I guess so if anybody wants to keep up with or investigate, goa, goa.design is probably the best place.

Speaker 1

是的。

Yes.

Speaker 1

在那里获取链接。

Get link there.

Speaker 0

是的。

And Yes.

Speaker 0

在你的 Slack 频道里,我想应该有一个 Go 学院。

On your Slack channel, I think would be there's a Go For Academy.

Speaker 0

所以是 gofirstslag.com,那里有一个 Goa 频道。

So gofirstslag.com, and there's a Goa channel there.

Speaker 1

没错。

That's right.

Speaker 1

而且你今年将在 GopherCon 上发言,如果我没记错的话,Brian 也会在 Abstractions 上关于 Goa 发言。

And you'll be actually speaking at GopherCon this year, and Brian will be speaking at Abstractions about Goa as well, if I'm correct.

Speaker 3

没错。

That's right.

Speaker 3

对于可能对在其中一场会议上了解 Goa 感兴趣的人,我们有一个重大公告。

And we have a big announcement for people who might be interested in learning about Goa at either one of those conferences.

Speaker 3

我联系了 Abstractions 的主办方,也和 Eric 谈过,我们都同意为这两场会议提供折扣码。

I talked to the organizer of abstractions, and I talked with Eric, and we both agreed to do a discount code for both conferences.

Speaker 3

所以,如果你在 GopherCon 或 Abstractions 上购票,可以享受 50 美元的折扣。

So you can get $50 off if you book at For Con or Abstractions.

Speaker 3

如果你使用代码 GOTIME,全部小写,没有空格,g o t I m e。

If you use the code GOTIME, all lowercase with, no space n, g o t I m e.

Speaker 3

所以使用 GOTIME 代码可以在任一会议中享受 50 美元折扣。

So GOTIME will get you $50 off either conference.

Speaker 3

如果你想去看拉斐尔在 Go For Con 上的演讲,或者去看我在 Abstractions 上关于 Goa 的演讲,Abstractions 的网站是 abstractions.io,Go For Con 的网站是 goforcon.com。

If you wanna go see Rafael talk at Go for Con or see me talk at Abstractions about Goa, abstractions.io is the website for Abstractions and goforcon.com for Go for Con.

Speaker 1

好的。

Alright.

Speaker 1

那我们来聊点轻松的话题吧。

So, let let's do some fireside chat here.

Speaker 1

新闻和有趣的项目。

News and interesting projects.

Speaker 1

我们非常欢迎你参与进来,拉斐尔,随时分享你发现的有趣内容或见解。

And we'd love for you to participate, Rafael, jump in wherever and offer your own input or things that you've come across you find interesting.

Speaker 0

很好。

Great.

Speaker 0

嗯。

Yep.

Speaker 0

听起来不错。

Sounds good.

Speaker 1

谁来开场?

Who wants to kick this thing off?

Speaker 2

我来吧。

I'll start.

Speaker 2

我想介绍一下我找到的一个命令行工具。

I would like to mention the CLI tool that I found.

Speaker 2

作者的名字不太清楚,但我认为他的仓库是 MK Ideal,项目叫 CLI。

The author's name is not very clear, but I'm going to say that his repo is MK Ideal in the project called CLI.

Speaker 2

我喜欢它,因为示例非常清晰,而且有很多示例。

I love it because the examples are super clear and there are tons of examples.

Speaker 2

我曾经用 Go 做过一个命令行应用。

I did a CLI app at some point in Go.

Speaker 2

如果我早看到这个,理解怎么做就会容易多了。

If I had seen this, it would have been so much easier for me to understand how to do it.

Speaker 2

它不仅有标志,还有命令。

It also has not only flags but commands.

Speaker 2

它看起来非常简洁清晰。

It seems very clean and neat.

Speaker 2

所以这就是我今天的推荐。

So that's my recommendation today.

Speaker 0

你如何将它与COBRA比较?

How would you compare it with a COBRA?

Speaker 0

我一直在用COBRA做Goa项目,但我很好奇。

I've been using COBRA for Goa, but I'm curious.

Speaker 2

我觉得它更容易理解和遵循。

I thought it was easier to understand and follow.

Speaker 2

如果我现在要使用COBRA,因为我以前用过,第一次用COBRA和Viper时,我会觉得很容易。

If I were if I am going to use COBRA today because I used it before, exactly the first time I used COBRA and Viper, I would have an easy time.

Speaker 2

但如果是第一次使用,这会非常简单。

But if it was my first time, I- this would be so easy.

Speaker 2

这会非常简单,因为文档太棒了。

This would have been so easy because the documentation documentation is amazing.

Speaker 2

致敬该项目的维护者。

Kudos to the to the project maintainer.

Speaker 1

是的。

Yeah.

Speaker 1

所以我只是快速看了看这个。

This so I I just quickly looked at this.

Speaker 1

但看起来它支持一些其他功能的集成。

So but it seems like it has kind of integrations for other things.

Speaker 1

比如,你可以将某个参数定义为 PID 文件,它会自动解析并给你一个指向该文件的指针,以便你以这种方式与之交互。

So like it can you can define a particular argument as a PID file, and it kind of decodes that and gives you a pointer to the file so you can interact with it that way.

Speaker 1

所以这种解码器的方式挺有意思的。

So it kind of is an interesting approach with these decoders.

Speaker 1

我得再仔细研究一下这个。

I'll have to look into this a little more.

Speaker 2

没错。

Exactly.

Speaker 2

而且你可以将标志定义为切片或映射,这些功能都已内置。

And you can use flag you can, define your flags as slice or map, and there are the features there.

Speaker 1

哦,这很有趣。

Oh, that's interesting.

Speaker 3

我本周的补充是Netflix的斯科特·曼斯菲尔德关于应用数据缓存的文章。

So my addition for this week is the post by Scott Mansfield from Netflix about application data caching.

Speaker 3

这篇文章内容太深入、太长,无法在这里详谈,但其中有一些关于数据存储和数据结构的精彩讨论,比如Go语言工具Rend项目,它在GitHub上是开源的。

And it is way too in-depth and too long to discuss here, but there are some really interesting discussions about data storage and data structure, Go tools like, the Rend project, which is available on GitHub open source.

Speaker 3

这是一篇非常出色、技术深度很高的文章,正是我喜欢在早晨喝咖啡时阅读的那种内容。

A very nice and technically in-depth article, just the sort of stuff that I love to wake up to with my coffee.

Speaker 3

而且文章里还提到了RocksDB,给你准备的,埃里克。

And it even has some RocksDB in there for you, Eric.

Speaker 1

是的。

Yeah.

Speaker 1

我超爱RocksDB。

I love me some RocksDB.

Speaker 1

是的。

Yeah.

Speaker 1

我也读了那篇帖子。

So I read that post too.

Speaker 1

实际上非常有趣。

It's actually really interesting.

Speaker 1

Rend与Memcached基本上是线兼容的。

Rend is, kind of wire compatible with Memcached.

Speaker 1

他们实际上实现了一个几乎位于客户端和Memcached之间的代理,设置了L1和L2缓存,让Memcached作为L1,但显然他们可以替换它。

And basically, what they, implemented was this proxy almost in between their clients and Memcached, and they implemented, like, an l one and l two cache so that Memcached was the L1, but obviously they could swap that out.

Speaker 1

然后他们使用RocksDB与SSD通信,作为类似L2缓存的机制。

And then they were using RocksDB to communicate, with their SSDs as kind of like an L2 cache.

Speaker 1

所有这些措施都是为了降低每月在亚马逊实例上的高昂内存成本,因为他们将大量用户数据存储在内存中。

And all of this was to reduce their financial costs monthly for their Amazon instances for high memory, because they were storing lots of user data in memory.

Speaker 1

因此,他们在每个区域都有一个热数据集,同时还有一个冷数据集,以便在用户从其他区域故障转移时能够应对。

And so they'd have kind of like the hot data set in a given region, but they'd also have a cold data set so in case, people fell over, failed over from another region and things like that.

Speaker 1

所以,他们节省的成本之多真的非常有趣。

So it's it's really interesting, how much they they dropped off.

Speaker 1

我很喜欢他们使用 RocksDB,现在有很多人都在用它。

And I love the fact that they're using RocksDB, and there's a lot of people using that now.

Speaker 1

有个叫 Mongo Rocks 的东西,不久前刚推出。

There's a, what, Mongo Rocks

Speaker 0

嗯。

Mhmm.

Speaker 1

没多久之前才发布的。

Was out not too long ago.

Speaker 1

我们另一个钟爱的数据库 CockroachDB,其底层也在使用 RocksDB,除非他们最近换了,但我认为他们现在还在用。

And, one of our other favorites, CockroachDB, they're using RocksDB under the covers, unless they've changed by now, but I think they're still using it.

Speaker 1

RocksDB 实际上源自 Facebook。

And, RocksDB actually comes out of Facebook.

Speaker 3

是的。

Yeah.

Speaker 3

我一定要特别感谢 Netflix 的 Scott 和他的团队,写了这么一篇精彩而详尽的文章。

I definitely just wanna shout out to Scott and the team at Netflix for such a nice and thorough write up.

Speaker 3

我知道 Scott 一直拉着那些愿意听的人,拖着他们进入 Go 世界。

I know Scott's been dragging the people who will listen, kicking and screaming into the Go world.

Speaker 3

尽管他们是一家以 Java 为主的公司,但后台其实有很多 Go 代码。

Even though they're they're a Java heavy shop, they do have a lot of Go behind the scenes there.

Speaker 3

他们只是不太谈论这个。

They just don't talk about

Speaker 0

很少提及。

it a lot.

Speaker 1

是的。

Yeah.

Speaker 1

我记得看过一些性能指标。

And, I I remember seeing some of the performance metrics.

Speaker 1

大概是每秒200万次请求,但我觉得这并不完全准确,因为当时还没有连接到后端。

It was it was something in the neighborhood of, like, 2,000,000 requests per second, but I think that wasn't, fully accurate because of that wasn't wired up to back end.

Speaker 1

我知道最终整个系统的性能大约是每秒2万到2万5千次插入。

I know when it all said and done, the whole system was something, in the neighborhood of, like, 20 or 25,000, inserts per second.

Speaker 1

但即便如此,这个Go代理提供的性能依然非常出色。

But still, I mean, the amount of performance that we're getting out of this, Go proxy is is awesome.

Speaker 1

我们也会在节目笔记中附上链接,因为那是一篇很有趣的阅读材料。

And we'll link to that in the show notes too, because that is an interesting read.

Speaker 1

特别是如果你对RocksDB和类似技术不太熟悉,会很有意思。

And especially if you're not familiar with kind of RocksDB and some of those things, that's kind of fun.

Speaker 1

通过了解日志结构合并树的工作原理,Cassandra也采用了类似的方法。

By getting to learn how, log structured merge trees work, Cassandra uses the kind of same approach there.

Speaker 3

是的。

Yeah.

Speaker 3

所以另一个我关注了很久的项目,但真正开始成熟起来是最近的事,是Stark and Wayne在GitHub上的Shield。

So another project that I've been following for a long time, but really, only recently has started to, mature is Shield from Stark and Wayne on GitHub.

Speaker 3

你们可能还记得Doctor。

You guys may remember Doctor.

Speaker 3

Ruby界的Nick。

Nick from the Ruby world.

Speaker 3

他似乎已经认可或拥抱了Go语言。

He seems to have endorsed Go or embraced Go.

Speaker 3

而且,这个工具Shield几乎是你备份东西的万能瑞士军刀。

And, this tool Shield is a, almost your universal utility knife for backing things up.

Speaker 3

所以你可以编写插件来备份Redis,可以备份数据库,可以备份磁盘,只要你为其编写插件,就能备份任何东西。

So you can write plug ins to back up Redis, you can back up a database, you can back up a disk, you can back up anything if you write a plugin for it.

Speaker 3

Shield刚推出时,我读了代码,因为GitHub上没有描述,只是试图猜测它最终会做什么,我花了几个月都没弄明白。

And Shield, when it first came out, I I read the code because there was no description in GitHub and and just tried to guess what it was going to do eventually, and I couldn't figure it out for quite a few months.

Speaker 3

现在它已经相当成熟了,看起来是一个备份所有东西的非常好的工具。

And now it's it's matured quite a bit, and it it looks to be a really nice tool for backing up all the things.

Speaker 1

嗯。

Yeah.

Speaker 1

我稍微看了一下那个。

I I briefly looked at that.

Speaker 1

我需要找一个使用场景。

I need to find a use case for it.

Speaker 1

但,是的。

But, yeah.

Speaker 1

我喜欢这种可以自行配置数据来源和目标位置的想法。

I I like the idea that you can kinda wire up, where it's pulling the data from and where it's pushing the data to.

Speaker 1

我需要更多时间。

I need more time.

Speaker 3

嗯。

Yeah.

Speaker 3

几乎就像我们上周讨论的Hecca的概念。

Almost like that the concept of Hecca we were talking about last week.

Speaker 3

你知道,这个是用于备份的Hecca。

You know, this is Hecca for backups.

Speaker 1

这个比喻其实很不错。

That's actually a good comparison.

Speaker 3

谢谢你说出这一点。

Thanks for saying so.

Speaker 3

我有

I have

Speaker 1

让你感觉好一点。

to make you feel better.

Speaker 3

经过这周我参与的代码审查,我什么都愿意接受。

After the code reviews I've been through this week, I'll take anything I can get.

Speaker 1

我见过的另一个有趣的项目是Uber的ZAP,这是一个结构化日志框架,据称可以实现零分配。

So another interesting project that I've seen was ZAP from Uber, which was a structured logging framework that, supposed to have, I think, zero allocations.

Speaker 1

所以这还挺有意思的。

So that was kind of interesting.

Speaker 3

你知道,我们在这南方,所以可以叫它 y'all,又一个分级日志系统。

You know, we're down here in the South, so we can call that y'all, yet another leveled logger.

Speaker 2

我真的很喜欢这个系统的结构部分。

I really liked the structure part of that system.

Speaker 2

我记得我以前在 Narelle 的应用工作时,我们用 Splunk 来追踪日志。

I remember when I worked, again, Narelle's app, and we were using Splunk to keep track of our logs.

Speaker 2

我们必须约定一种特定的编码方式,以便在 Splunk 中轻松查找。

And we had to agree upon a specific way to write our code so that it will be easy to find in Splunk.

Speaker 2

然后我们还得加上某些关键词、等号以及我们想查看的变量。

And then we have to just like put certain keywords and the equal sign and whatever variable we wanted to look at.

Speaker 2

我们还得依赖每个人都能记得这样做。

And we had to rely upon everybody remembering to do that.

Speaker 2

所以这种结构让每个人的生活都简单多了,而且它看起来也非常高效,功能也很强大。

So with this structure, just makes life so much simpler for everybody, besides the fact that it seems to be very efficient and about features.

Speaker 1

好的。

Alright.

Speaker 1

还有没有人想在我们各自散去前说点别的?

Anybody have anything else they want to talk about before we kind of go on our merry way?

Speaker 3

没有,这期节目内容很丰富。

No, it's been a pretty full show.

Speaker 1

或者对布莱恩来说不太愉快,因为他的代码审查要被狠狠挑刺了。

Or not so merry for Brian who's going to get a beat down in his code review Go

Speaker 3

回到我的代码审查系统。

back to my code review system.

Speaker 3

如果布莱克在听,别告诉他。

Don't tell Blake if he's listening.

Speaker 1

所以,我们在节目结束时喜欢做的一件事就是简要地轮流感谢一个开源项目,就像你之前提到的,拉斐尔,来自社区的这种反馈有时真的能让人心情大好。

So, one of the things we like to do when we close the show is just kind of briefly go around and, give thanks to an open source project, kind of as you spoke to earlier, Rafael, to kind of, to get kind of that feedback from the community sometimes makes your day.

Speaker 1

所以我们希望定期表达感谢,感谢那些让我们的生活更轻松的人。

So we want to make sure that we're regularly reaching out and thanking people for the things that make our lives easier.

Speaker 1

布莱恩,你来带头吧?

You want to kick this off, Brian?

Speaker 3

我今天来开场。

I'll kick it off today.

Speaker 3

我最喜爱的开源工具之一是Bitly的NSQ。

One of my favorite open source tools ever is NSQ from Bitly.

Speaker 3

我已在数十个项目中使用过NSQ,它从未让我失望过。

I've used NSQ in dozens of projects, and it has never ever disappointed me.

Speaker 3

它速度极快。

It is blazing fast.

Speaker 3

它完全可预测且可靠,用很少的代码就能用NSQ完成惊人的工作。

It is a 100% predictable and reliable, and it's just amazing how much you can do, with NSQ in very little code.

Speaker 3

我非常感谢他们将它开源。

And I I really appreciate the fact that they open source that.

Speaker 3

这真是个很棒的工具。

It's it's a great tool.

Speaker 2

它是什么?

What is it?

Speaker 3

NSQ 是一个分布式队列,具有极强的容错性和极快的速度,它是用 Go 语言编写的。

NSQ is it's a distributed queue that's incredibly fault tolerant and really fast, and it's written in Go.

Speaker 3

而且它的代码写得非常巧妙。

And it's just it's it's written really smartly.

Speaker 1

是的。

Yeah.

Speaker 1

实际上,马特·理查德森在 2014 年的 GopherCon 上做过关于它的演讲。

And so actually, Matt Richardson did a talk in GopherCon twenty fourteen on it.

Speaker 1

我觉得演讲标题大概是‘往上面撒点 NSQ’之类的。

I think the talk was titled something like spray some NSQ on it or something

Speaker 3

对,就是这样。

like That's right.

Speaker 1

是的。

Yeah.

Speaker 1

但没错,那个演讲应该也在 GitHub 上。

But yeah, that that should be on GitHub too.

Speaker 3

这个视频已经上传了,是的。

That video is up on Yeah.

Speaker 1

你呢,Carlicia?

How about you, Carlicia?

Speaker 2

我想提一下今天的第二项内容,我相信大多数人可能已经知道了,但如果你还不知道,绝对应该去看看,因为迟早你会用到的。

I would like to mention today item two, which If I'm sure most people already you don't, you definitely should check it out because eventually you will.

Speaker 2

似乎每个人都会从苹果系统自带的终端切换到iTerm2。

It seems that everybody makes a transition from the normal terminal that comes with the Apple system to iTerm2.

Speaker 2

尤其是2.9测试版。

And especially the 2.9 beta version.

Speaker 2

我因为某些原因下载了它,但现在已经忘了具体原因,已经过去几个月了。

I had to download that for some reason that I forgot, and it's been a couple of months.

Speaker 2

它太棒了。

And it's amazing.

Speaker 2

它新增了许多非常有趣且实用的功能。

There are a bunch of new features that are very interesting, very useful.

Speaker 2

我只是想说,我建议你离开。

I'm just going to say I recommend you leave.

Speaker 2

它每天都会在终端上弹出一个每日提示。

It pops up a tip of the day every day, right on the terminal.

Speaker 2

它非常不打扰人。

It's very non intrusive.

Speaker 2

我们只需按一下 Escape 键,它就会消失。

We can just keep escape and it'll go away.

Speaker 2

基本上,保持开启这个功能,你就能发现终端中一大堆酷炫的功能。

Basically, leave that on and you're going to just cover a treasure trove of cool features for your terminal.

Speaker 2

就这些。

There.

Speaker 2

完了。

That's it.

Speaker 1

是的。

Yeah.

Speaker 1

最近当我使用我的Mac时,我会开启那些小提示。

For when I am actually on my Mac recently, I have the little tips on there.

Speaker 1

因为已经有一段时间没探索过新增的功能了,所以我让这些提示时不时地打扰我,提醒我一些应该去做的事情。

It's because it's been a while since I've explored features added, so I'm letting it annoy me periodically to tell me things that I should be doing.

Speaker 3

他们也为iTerm添加了一些非常激进的功能。

They've added some really radical stuff to iTerm too.

Speaker 3

最新的测试版在新增的功能方面简直令人疯狂。

The the latest betas are pretty crazy in terms of the the toys that they've added.

Speaker 3

我不确定自己会不会用上所有这些功能,但它们确实令人印象深刻。

I'm not sure if I'll ever use them all, but they are impressive.

Speaker 1

我有点嫉妒,因为大多数时候我都是在Linux工作站上工作。

I get a little jealous because most of the time I work off of my Linux workstation.

Speaker 1

所以,你知道的,我现在用的是Gnome Terminal,也就是I3。

So, you know, Gnome Terminal, I think, is the current one I'm using, in I three.

Speaker 1

但没错,就是不一样。

But, yeah, it's just it's not the same.

Speaker 1

拉斐尔,你有想过的项目吗?

Rafael, do you have a project you'd like to think?

Speaker 0

有的。

Yeah.

Speaker 0

实际上,我们开始使用RethinkDB,这非常有趣。

Actually, we started using RethinkDB, and it has been very interesting.

Speaker 0

我偶然发现了它,读了它的功能描述,一切听起来都很好,就像通常那样。

I stumbled on it kind of by chance and was reading description of the feature set and it all sounded good like it usually does.

Speaker 0

但真正让我印象深刻的是,它与我们想要的使用场景非常契合,那就是在数据更新时生成事件。

But then what really struck me is how well it fit with the use case that we were after, which was trying to generate events whenever some data was updated.

Speaker 0

RethinkDB内置了这种订阅机制。

So RethinkDB has that built in, this idea of subscriptions built in.

Speaker 0

这是一段非常有趣的经历。

And it's been a very interesting journey.

Speaker 0

它极大地改变了我们对这些新服务设计的思考方式。

It has changed quite a bit the way we're thinking about the design for those new services.

Speaker 0

所以我强烈推荐还没试过的人去了解一下,因为它为如何设计系统并利用这些订阅功能提供了另一种思路。

And so I would definitely recommend people take a look at it if they haven't yet because it does provide another dimension to how you can design your systems and take advantage of these subscriptions capabilities.

Speaker 0

所以非常高兴他们将它开源了。

So very, very glad that they open sourced that.

Speaker 0

还有另一件事我想提一下,这不是一个项目,但我想要表扬所有允许员工开发开源项目的公司,对吧?

And something else I wanted to mention, s not a project, but I wanted to give a shout out to all the companies that let their employees develop open source projects, right?

Speaker 0

因为这需要时间。

Because it takes time.

Speaker 0

我们总得谋生,不是吗?

S not that we all have to make a living.

Speaker 0

最终,允许员工开发开源项目的公司本身就是推动者,我认为我们应该感谢他们。

And at the end of the day, the companies that allow their employees to develop open source projects are already enablers and I think we need to thank them for that.

Speaker 0

我当然要感谢Rescale在Goa方面的支持,但不仅仅是我还想到了J。

I m thankful for Rescale obviously with Goa but it's not just just I was also thinking about J.

Speaker 0

P。

P.

Speaker 0

纽约时报的罗宾逊,你知道的,他在做Gizmo。

Robinson at New York Times, you know, doing Gizmo.

Speaker 0

我的意思是,有很多例子,那些在业界工作的人,他们的公司实际上支付他们开发开源项目。

I mean, there's there are many, many examples of people that work in industry and and where their company actually pay them to develop open source projects.

Speaker 0

所以我觉得这太棒了。

So I think that's awesome.

Speaker 1

我其实可以耍个赖,因为我们刚好可以聊聊Netflix的帖子和RoxDB,我超爱RoxDB,所以我要为他们点赞。

And I actually get to cheat because we got to just talk about the Netflix post and RoxDB, and I love RoxDB, so I'm gonna give a shout out to them.

Speaker 3

这算作弊。

That's cheating.

Speaker 3

这根本不该算数。

That shouldn't even count.

Speaker 3

埃里克,这个我们从你的得分里划掉。

We're taking this one off your scoreboard, Eric.

Speaker 1

但我的意思是,这太棒了。

But, I mean, it's awesome.

Speaker 1

我的意思是,如果还有人没玩过,他们应该试试。

I mean, if anybody hasn't played with it, they should.

Speaker 1

甚至只是研究一下日志结构合并树的工作原理,都相当有趣。

And even just investigating kinda how log structured merge trees work is kind of fascinating.

Speaker 1

所以我认为,我们就差不多要到时间了。

So I think with that, we are, I think, just about out of time.

Speaker 1

我真心感谢大家参加本期节目,特别感谢拉斐尔前来和我们讨论生成各种东西的话题。

So I definitely wanna thank everybody for being on the show, and especially Rafael for coming on and talking to us about generating all the things.

Speaker 0

谢谢。

Thank you.

Speaker 0

这真是太棒了。

This this has been great.

Speaker 0

非常感谢。

Thank you very much.

Speaker 1

我们今天请到了代码生成之父做客节目。

We we have the godfather of code generation on the show.

Speaker 0

不。

No.

Speaker 0

这真的非常好。

This this has been really great.

Speaker 0

感谢您给予这个机会。

Thank you for the opportunity.

Speaker 0

我非常感激。

I really appreciate it.

Speaker 1

我们会在节目笔记中提供我们所讨论内容的链接,或者如果您在Twitter上关注我们@Gotime FM。

And we'll have links to everything we've talked about in the show notes or if you happen to be following us on Twitter at Gotime FM.

Speaker 1

大部分内容都会链接到那里,或者在Gopher Slack或Go Goodtime FM的Slack频道中也可以找到。

Most of this stuff should be linked there or the Slack channel, the Gopher Slack or Go Goodtime FM there as well.

Speaker 1

是的。

Yeah.

Speaker 1

我想就这样了。

So I think that is about it.

Speaker 1

那么,我想我们下周再会。

And with that, I guess we'll see everybody next week.

Speaker 3

太棒了。

Awesome.

Speaker 3

谢谢大家。

Thanks everybody.

Speaker 2

谢谢。

Thank you.

Speaker 2

再见。

Goodbye.

Speaker 0

拜拜。

Bye.

关于 Bayt 播客

Bayt 提供中文+原文双语音频和字幕,帮助你打破语言障碍,轻松听懂全球优质播客。

继续浏览更多播客