使用AWS lambda go api代理学习如何运行go rest apis作为lambda函数。
Go编程语言一直对构建REST API有丰富的支持。其中包括一个excellent standard library (net/http)以及许多受欢迎的套餐,例如gorilla mux,Gin,negroni,echo,fiber等。
感谢AWS Lambda Go runtime,您可以使用Go构建AWS lambda函数。想象一个Web应用程序,需要对用户进行身份验证,存储用户数据并发送电子邮件。无服务器的方法将将每个功能/API作为单独的lambda函数实现。例如,您可以具有lambda功能来处理用户注册,另一个用于处理用户登录等等。
如果您从头开始构建所有内容,这是很棒的。但是,如果您想作为AWS lambda函数运行现有的Go Rest API怎么办?
从广义上讲,您需要:
- 将现有代码分为多个lambda函数。
- 重构每个人都可以与AWS Lambda Go Runtime Apis一起工作。
使用 aws lambda go api代理,有一种更简单的方法!
此博客将通过AWS Lambda和Amazon API网关以无服务器方式演示如何以无服务器方式运行现有的API。您将详细介绍net/http
软件包,gorilla
和echo
框架的简单代码示例,以了解它们如何使用AWS Serverless Application Model。
该代码可在此GitHub repository
中找到
让我们从简要介绍AWS Lambda Go API代理。
AWS Lambda Go API代理:它如何工作?
aws-lambda-go-api-proxy软件包使使用AWS Lambda和Amazon API Gateway的Frameworks(例如杜松子酒)编写的API轻松运行API。除了用于net/http
(GO标准库)和其他框架(例如gorilla/mux
,echo
等)的适配器实现外,aws-lambda-go-api-proxy
还宣布了一个core
软件包,该软件包包含实用程序方法和接口,将API Gateway Proxy Proxy Events转换为GO的default http.Request
和http.Request
和http.Request
和http.ResponseWriter
对象并允许您将任何任何框架适应AWS lambda go Runtime。
这是关于它如何在高级别上工作的要点:
- API网关请求被Lambda功能处理程序接受。
- 函数处理程序将请求代理到与框架相对应的适配器实现。
- 最后,API网关代理响应返回给客户端。
让我们研究特定框架的行为。
大猩猩/Mux图书馆
软件包gorilla/mux
实现了请求路由器和调度程序,以将传入请求与其各自的处理程序匹配。就像GO标准库中的http.ServeMux
一样,mux.Router
将传入的请求与注册路线列表匹配,并呼叫与与URL或其他条件相匹配的路线的处理程序。因为gorilla/mux
实现了http.Handler
接口,所以它与http.ServeMux
兼容。
这是使用适配器实现与gorilla/mux
软件包合作的lambda函数的简单示例:
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)
}
- 在
init
函数中:gorillamux.New
函数接收到mux.Router
(已定义了HTTP
GET
路线)并返回gorillamux.GorillaMuxAdapter
。 - 在
Handler
实施中:-
gorillamux.GorillaMuxAdapter
对象的Proxy
(或ProxyWithContext
)接收events.APIGatewayProxyRequest
,将其转换为http.Request
对象,然后将其发送到mux.Router
进行路由。 - 它返回从写入响应作者(
http.ResponseWriter
)的数据生成的代理响应对象(events.APIGatewayProxyResponse
)。
-
回声框架
回应另一个流行的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)
}
该概念类似于上一个示例。
-
init
函数设置了路由器(echo.Echo
)并将其传递到echoadapter.New
thar返回echoadapter.EchoLambda
(适配器实现)。 - 在
Handler
函数中:-
echoadapter.EchoLambda
对象的ProxyWithContext
方法接收events.APIGatewayProxyRequest
对象并将其转换为http.Request
对象并将其发送到echo.Echo
以进行路由。 - 它返回从写入响应作者(
http.ResponseWriter
)的数据生成的代理响应对象(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)
}
- 要与标准库一起使用,
httpadapter.New
函数将带有http.Handler
(已定义路由)并返回httpadapter.HandlerAdapter
对象。 -
httpadapter.HandlerAdapter
上的ProxyWithContent
方法然后可以用作lambda处理程序。
让我们看看这在实践中的工作方式。
部署到AWS Lambda
让我们使用Sam Cli。
先决条件
在继续之前,请确保已安装Go programming language( v1.18 或更高)和AWS SAM。
克隆项目并更改为正确的目录:
git clone https://github.com/build-on-aws/golang-apis-on-aws-lambda
cd golang-apis-on-aws-lambda
大猩猩/基于Mux的Lambda功能
首先,将template.yaml
中的CodeUri
更新为gorilla/
(这是代码所在的本地文件夹)。
构建功能:
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 CloudFormation
控制台检查已部署的堆栈和相关资源。其中包括lambda功能,API Gateway (REST API),IAM角色等。
您应该将API网关端点视为SAM CLI输出(在您的情况下会有所不同)或CloudFormation
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网关:
export API_ENDPOINT=<enter the API Gateway endpoint here>
curl $API_ENDPOINT
您应该得到类似于以下内容的JSON
响应:
{
"from": "gorilla",
"message": "Tue Jun 27 18:10:54 UTC 2023"
}
NET/HTTP和基于回声的Lambda功能
在部署任何一个之前,请确保更新template.yaml
中的CodeUri
以参考代码所在的本地文件夹:
-
http-stdlib/
在net/http
套件的情况下。 -
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网关端点来测试功能:
export API_ENDPOINT=<enter your API endpoint here>
curl $API_ENDPOINT
您应该得到类似于以下内容的JSON
响应:
{
"from": "net/http",
"message": "Tue Jun 27 18:20:42 UTC 2023"
}
在echo
框架的情况下,您应该得到类似于以下的JSON
响应(请注意from
字段中的不同名称):
{
"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
)如何使用特定的适配器实现,允许您在AWS Lambda函数上运行现有的GO应用程序。您通过简单的代码示例学习了基本概念,使用AWS SAM CLI部署了这些功能,并通过调用API网关端点进行了验证。
AWS Lambda Go API代理还支持Gin,这是最受欢迎的Go Web框架之一!该博客的第二部分将演示如何在AWS Lambda函数的借助简单(但实用的)URL Shortener Service函数时运行现有的Gin
框架应用程序。
请继续关注!