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运转时中。

如何以无服务器方式运行 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函数

首先,将CodeUritemplate.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角色等。

如何以无服务器方式运行 Go 应用程序

可以在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开发工具等