Go编程言语一直以来都对构建REST API提供了丰厚的支撑。这包括一个超卓的规范库(net/HTTP),以及许多盛行的包,如Gorilla mux、Gin、Negroni、Echo、Fiber等。运用AWS Lambda Go运转时,咱们可以运用Go构建AWS Lambda函数。想象一下,一个Web应用程序需要对用户进行身份验证、存储用户数据和发送电子邮件。采用无服务器的办法,可以将每个功能/API完成为单独的Lambda函数。例如,咱们可以有一个Lambda函数来处理用户注册,另一个来处理用户登录,依此类推。假如咱们从头开端构建一切,这很好。但是,假如咱们想将现有的Go REST API作为AWS Lambda函数运转,该怎么办呢?大体上来说,您需要进行以下操作:
-
将现有的代码拆分为多个Lambda函数。
-
重构每个函数以适配AWS Lambda Go运转时API。
不过运用AWS Lambda Go API Proxy,有一种更简略的办法。接下来将演示怎么运用AWS Lambda和Amazon API Gateway以无服务器方式运转根据Go结构的现有API。将经过简略的代码示例和结构来了解它们的作业原理,并运用AWS Serverless Application Model(SAM)布置它们。代码可在此GitHub存储库中找到。让咱们从AWS Lambda Go API Proxy的扼要介绍开端。
AWS Lambda Go API Proxy:它是怎么作业的?
aws-lambda-go-api-proxy包使得运用结构(如Gin)编写的Go API可以轻松地在AWS Lambda和Amazon API Gateway上运转。除了适配器完成(针对Go规范库)和其他结构(如,,等)外,aws-lambda-go-api-proxy还声明晰一个包,其间包含了将API Gateway署理事情转换为Go默许和目标的有用办法和接口,并答应您将任何结构适配到AWS Lambda Go运转时中。
下面是它的高级作业原理概述:
-
Lambda函数处理程序接纳API Gateway的恳求。
-
函数处理程序将恳求署理到与结构对应的适配器完成。
-
最终,将API Gateway署理呼应回来给客户端。
再让咱们深入了解一下特定于结构的行为。
gorilla/mux库
gorilla/mux包完成了一个恳求路由器和调度器,用于将传入的恳求与其相应的处理程序进行匹配。与Go规范库中的相似,它将传入的恳求与注册的路由列表进行匹配,并调用与URL或其他条件匹配的路由的处理程序。因为完成了接口与其他的兼容。下面有一个简略的Lambda函数示例,运用适配器完成与gorilla/mux包一同运用:
var gorillaLambda *gorillamux.GorillaMuxAdapter
func init() {
r := mux.NewRouter()
r.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(Response{From: "gorilla", Message: time.Now().Format(time.UnixDate)})
})
gorillaLambda = gorillamux.New(r)
}
func Handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
r, err := gorillaLambda.ProxyWithContext(ctx, *core.NewSwitchableAPIGatewayRequestV1(&req))
return *r.Version1(), err
}
func main() {
lambda.Start(Handler)
}
在这个函数中:函数接纳一个 http.Request
目标(其间定义了路由),并回来一个 http.Response
目标。在完成中:Handler
目标的 ServeHTTP
办法接纳 http.Request
目标,将其转换为 http.ResponseWriter
目标,并将其发送到路由器进行路由处理。它将依据写入到呼应写入器的数据生成一个署理呼应目标(http.Response
)。
Echo结构
Echo是另一个盛行的Go Web结构,它既简约又高度可扩展。下面是一个简略的Lambda函数示例,运用适配器完成与Echo结构一同运用:
var echoLambda *echoadapter.EchoLambda
func init() {
e := echo.New()
e.Use(middleware.Logger())
e.Use(middleware.Recover())
e.GET("/ping", func(c echo.Context) error {
return c.JSON(http.StatusOK, Response{From: "echo", Message: time.Now().Format(time.UnixDate)})
})
echoLambda = echoadapter.New(e)
}
func Handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
return echoLambda.ProxyWithContext(ctx, req)
}
func main() {
lambda.Start(Handler)
}
该函数设置了一个路由器(echo.Echo
),并将其传递给 echoadapter.New
函数,回来一个适配器完成(echoadapter.EchoLambda
)。在函数中:Handler
目标的 ProxyWithContext
办法接纳 events.APIGatewayProxyRequest
目标,并将其转换为 http.Request
目标,然后将其发送到 echo.Echo
进行路由处理。它将依据写入到呼应写入器的数据生成一个署理呼应目标(events.APIGatewayProxyResponse
)。
net/http
关于net/http包,适配器完成的作业方式也是相同的。以下是代码片段的示例:
var httpLambda *httpadapter.HandlerAdapter
func init() {
http.HandleFunc("/ping", func(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(Response{From: "net/http", Message: time.Now().Format(time.UnixDate)})
})
httpLambda = httpadapter.New(http.DefaultServeMux)
}
func Handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
return httpLambda.ProxyWithContext(ctx, req)
}
func main() {
lambda.Start(Handler)
}
要与规范库一同运用,该函数接纳一个 http.Handler
目标(其间定义了路由),并回来一个 httpadapter.HandlerAdapter
目标。然后,可以运用 ProxyWithContext
办法将其作为Lambda处理程序。
布置到AWS Lambda
运用SAM CLI将这些函数布置到AWS Lambda。
先决条件
需要安装了Go编程言语(v1.18或更高版本)和AWS SAM。克隆项目并切换到正确的目录。
git clone https://github.com/build-on-aws/golang-apis-on-aws-lambda
cd golang-apis-on-aws-lambda
根据gorilla和mux的Lambda函数
首先,将CodeUri
在template.yaml
文件中更新为代码地点的本地文件夹途径。构建函数:
sam build
#expected output
Building codeuri: <path>/lambda-go-api-proxy-getting-started/gorilla runtime: go1.x metadata: {} architecture: x86_64 functions: DemoFunction
Running GoModulesBuilder:Build
Build Succeeded
....
布置函数(依照SAM CLI的提示进行操作):
export STACK_NAME=lambda-go-gorilla
sam deploy --stack-name $STACK_NAME --guided
# response to the prompts
Stack Name [lambda-go-gorilla]: <press enter>
AWS Region [us-east-1]: <enter alternate region or press enter>
#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
Confirm changes before deploy [y/N]: n
#SAM needs permission to be able to create roles to connect to the resources in your template
Allow SAM CLI IAM role creation [Y/n]: y
#Preserves the state of previously provisioned resources when an operation fails
Disable rollback [y/N]: n
DemoFunction may not have authorization defined, Is this okay? [y/N]: y
Save arguments to configuration file [Y/n]: y
SAM configuration file [samconfig.toml]: <press enter>
SAM configuration environment [default]: <press enter>
布置完成后,转到AWS控制台,检查已布置的堆栈和相关资源。这些资源包括Lambda函数、API Gateway(REST API)、IAM角色等。
可以在SAM CLI的输出中看到API Gateway的端点,或者在Outputs部分中找到它。
-----------------------------------------------------------------------------------------------------
CloudFormation outputs from deployed stack
--------------------------------------------------------------------------------------------------------
Outputs
--------------------------------------------------------------------------------------------------------
Key APIGWEndpoint
Description API Gateway Endpoint
Value https://whrd2yy3ug.execute-api.us-east-1.amazonaws.com/dev/ping
--------------------------------------------------------------------------------------------------------
Successfully created/updated stack - lambda-go-gorilla in us-east-1
要测试函数,请运用以下指令调用API Gateway:
export API_ENDPOINT=<enter the API Gateway endpoint here>
curl $API_ENDPOINT
会得到相似以下的呼应:
{
"from": "gorilla",
"message": "Tue Jun 27 18:10:54 UTC 2023"
}
net/http和根据echo的Lambda函数
在布置这两个函数之前,请确保将CodeUri
更新为代码地点的本地文件夹途径:- 关于net/http
包,更新为http-stdlib/
。- 关于echo
结构,更新为echo/
。构建并布置函数(依照之前的提示进行操作):
sam build
# change the stack name to lambda-go-echo in case of "echo" framework
export STACK_NAME=lambda-go-nethttp
sam deploy --stack-name $STACK_NAME --guided
可以经过调用API Gateway端点来测试函数:
export API_ENDPOINT=<enter your API endpoint here>
curl $API_ENDPOINT
会得到下面的呼应:
{
"from": "net/http",
"message": "Tue Jun 27 18:20:42 UTC 2023"
}
关于结构的情况,会得到下面的呼应(留意字段中的不同称号):
{
"from": "echo",
"message": "Tue Jun 27 18:30:25 UTC 2023"
}
以上过程已成功将Go API布置为AWS Lambda函数。完成后,请删除堆栈:
sam delete --stack-name lambda-go-gorilla
sam delete --stack-name lambda-go-nethttp
sam delete --stack-name lambda-go-echo
结论
上面演示了AWS Lambda Go API署理,以及它的结构/包(关于gorilla/mux、echo和net/http)特定的适配器完成,可以将现有的Go应用程序作为AWS Lambda函数运转,并由API Gateway提供前端服务。经过简略的代码示例学习了基本概念,运用AWS SAM CLI布置了这些函数,并经过调用API Gateway端点进行了验证。
作者:Abhishek Gupta
更多技术干货请关注公众号“云原生数据库”
squids.cn,现在可体验全网zui贱价RDS,免费的迁移工具DBMotion、SQL开发工具等。