amazon-web-services - 在 Go 中为 AWS Lambda 指定多个事件处理程序
问题描述
通常,Go 中的 AWS Lambda 事件处理程序代码(使用无服务器框架)编码为:
package main
import (
"fmt"
"context"
"github.com/aws/aws-lambda-go/lambda"
)
type MyEvent struct {
Name string `json:"name"`
}
func HandleRequest(ctx context.Context, name MyEvent) (string, error) {
return fmt.Sprintf("Hello %s!", name.Name ), nil
}
func main() {
lambda.Start(HandleRequest)
}
然后该serverless.yml
文件包含如下部分:
skeleton-go-get:
name: skeleton-go-get
runtime: go1.x
handler: go-handler # <- This specifies a file, not a function.
events:
- http:
path: skeleton/go
method: get
那 ^ 创建了一个请求处理程序......但现在我希望我的一个 Go 脚本/程序包含 HTTP GET 和 POST 请求的事件处理程序,而不是每个无服务器函数使用一个 Go 程序文件。
这在 Node.js、Ruby、Python 等语言中完全可以实现,并serverless.yml
指定处理程序文件中的哪个函数将用于哪个无服务器函数。例如(对于 Python 函数):
[...]
functions:
skeleton-python-get:
name: skeleton-python-get
handler: python-handler.handle_get # <- Specifies the HTTP GET handler.
events:
- http:
path: skeleton/python
method: get
skeleton-python-post:
name: skeleton-python-post
handler: python-handler.handle_post # <- Specifies the HTTP POST handler.
events:
- http:
path: skeleton/python
method: post
我无法在 Go 中使用同样的技巧。我试图在其中包含正确的请求,main()
但无济于事:
func HandleGetRequest(ctx context.Context, name MyEvent) (string, error) {
return fmt.Sprintf("Hello %s!", name.Name ), nil
}
func HandlePostRequest(ctx context.Context, name MyEvent) (string, error) {
return fmt.Sprintf("Hello %s!", name.Name ), nil
}
func main() {
lambda.Start(HandleGetRequest)
lambda.Start(HandlePostRequest) // <- Attempt to add another handler.
}
并且在文件中为 Go 处理程序指定多个事件处理程序函数serverless.yml
也不起作用:该函数不是处理程序声明的有效部分。
skeleton-go-get:
name: skeleton-go-get
runtime: go1.x
handler: go-handler.HandleGet # <- Attempt to specify a function.
events:
- http:
path: skeleton/go
method: get
skeleton-go-post:
name: skeleton-go-post
runtime: go1.x
handler: go-handler.HandlePost # <- Attempt to specify a function.
events:
- http:
path: skeleton/go
method: post
问:如何在一个 Go 程序中包含多个 AWS Lambda 事件处理程序(使用无服务器框架)?
解决方案
get
您可以为 your和 your使用相同的函数(和处理程序)post
:
skeleton-go:
name: skeleton-go
runtime: go1.x
handler: go-handler
events:
- http:
path: skeleton/go
method: get
- http:
path: skeleton/go
method: post
使用 Go 的内置 HTTP 路由器或使用第三方的,例如Gorilla Mux或Chi,如下面的示例代码所示(因为这是我方便的)。本质上,您正在构建一个 Go HTTP 服务器,但使用的是 Lambda。因此,请按照设置 Go Web 服务器的详细信息,并查看AWS 的 API Gateway 代理。
package main
import (
"context"
"net/http"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/go-chi/chi"
chiproxy "github.com/awslabs/aws-lambda-go-api-proxy/chi"
)
var adapter *chiproxy.ChiLambda
func GetSkeleton(w http.ResponseWriter, r *http.Request) {
...
}
func PostSkeletonToMom(w http.ResponseWriter, r *http.Request) {
...
}
func init() {
r := chi.NewRouter()
r.Get("/skeleton/go", GetSkeleton)
r.Post("/skeleton/go", PostSkeletonToMom)
adapter = chiproxy.New(r)
}
func lambdaHandler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
c, err := adapter.ProxyWithContext(ctx, req)
return c, err
}
func main() {
lambda.Start(lambdaHandler)
}
推荐阅读
- shell - 如何在 telnet 会话中循环执行命令
- amazon-web-services - 在 Keda 中对 AWS SQS 缩放器进行身份验证
- php - Laravel 请求路由并检查用户是否通过 ajax 登录
- mysql - 减去基于使用 MySQL 的数据的值
- docker - 如何在 Dockerfile 中使用暴露
- node.js - 延迟执行异步函数数组,节点js
- flutter - 从 Firebase 加载数据缓慢导致“RangeError(索引)”
- linux - PHP在root用户而不是www-data上运行
- avaloniaui - Avalonia - 如何像 OneNote 桌面 UI 一样垂直放置 Tab 控件的选项卡
- winforms - 在文本框中书写时如何按 Enter?