在Go应用程序中抽象网络库

186 阅读3分钟

在Go应用程序中抽象网络库

2015年,在使用PHP作为主要编程语言十多年后,我开始用Go开发项目。在这次迁移中,我受到的第一个影响是没有像Zend Framework、Symfony或Laravel这样的Web框架。

经过一些研究,我了解到Go社区采用的方法是不同的。开发人员并没有采用复杂的框架,而是热衷于遵循语言谚语,比如说Clear is better than clever。为了实现这一点,除其他外,人们广泛使用语言的伟大标准库。

Go有一个由几个方便的包组成的库,其中一个是http, 它提供了功能并定义了实现HTTP客户端和服务器的标准接口。基于这些接口,出现了一些便于开发的库。如:

这一系列的选择给了团队自由,但在大公司里可能会有问题,因为每个项目都可能使用不同的库。为了解决这个问题,在PicPay,我们开发了一个库,它包含了标准库的接口,保证了兼容性,而不限制团队选择。

我将在这篇文章中向你展示一些代码片段来证明这个概念。

创建抽象

给出下面的例子项目。

internal/api/package里面,我创建了API Go文件。

Start函数接收HTTP服务器将要监听的端口,http.Handler接口的一些实现,以及一个参数列表。我们将使用这个参数列表来配置读和写超时。如果这个人没有传递这些设置,包将使用默认的30秒超时。在收到这些信息后,该函数可以启动一个HTTP服务器,并添加Graceful shutdown的配置,这是一个好的做法。

实现处理程序

下一步是使用其中一个库来实现http.Handler接口。例如,让我们先用Gin库来实现它。我创建了internal/http/gin包和里面的book.go文件。

在我们应用程序的函数中,我们现在可以使用这两种实现来启动HTTP服务器并响应用户请求。

如果任何团队想使用Fiber库,他们需要开发http.Handler接口的实现,如文件internal/http/fiber/book.go

而main.go中唯一需要改变的是将处理程序的初始化从h := gin.Handlers(s)替换为h := fiber.Handlers(s),其他一切都会正常。

增加全局功能

另一个好处是,我们现在可以使用api包的Start函数,使用中间件向我们的应用程序添加 "全局 "功能。

在文件internal/api/api.go中,我做了两个改动。第一个是创建了一个新的函数。

而第二个改动是在Start函数中使用这个中间件。为了使管理中间件更容易,我使用了一个叫Negroni的库,它使代码更有组织。我修改的片段看起来像这样。

如果你想添加指标收集、访问控制和速率限制等功能,这种方法很方便。

我想强调的最后一个提示是,无论何时你用Go开发应用程序,都要尽可能地忠于语言的标准库所提供的接口。这样一来,你就可以确保对版本的兼容性,并减少对外部库和框架的依赖性。