为 CRUD 操作设计 AWS lambda 函数的最佳方法是什么

问题描述

对于 CRUD 应用程序,设计 AWS lambda 函数的最佳方法是什么:

  1. 创建一个 lambda 函数,并在处理程序中使用 switch case 区分每个调用
  2. 创建一个单独的 lambda 函数,但每个调用都有一个单独的处理程序。甚至有可能吗?
  3. 为每个操作创建一个单独的 lambda 函数

由于这些只是简单的 CRUD 操作,因此大小不是一个重要因素。但我对管理和成本效益有点担心。

解决方法

我们通常采用您的方法 #3 - 每个操作都有一个单独的 lambda 函数。为了克服代码管理的顾虑,我们使用 AWS SAM

我们使用 API Gateway 向客户端公开 Lambda 函数。所以请求看起来像这样 -

/createUser API -> CreateUserLambdaFunction
/getUser API -> GetUserLambdaFunction
...
...

而且代码结构是这样的——

index.js(所有 lambda 函数的处理程序)

import { DbAccessor } from './accessors/db-accessor';
exports.create_user = async(event) => {
  ...
  DbAccessor.createUser(event..)
}
exports.get_user = async(event) => {
  ...
  DbAccessor.getUser(event..)
}

db-accessor.js

Common file for all Lambda functions. contains all the CRUD interactions with the db.

最后,为了将所有这些整合在一起并一次性部署所有 Lambda 函数,我们使用了 AWS SAM。 SAM 需要一个 template.yml 文件来包含需要创建的所有 AWS 资源的定义,在我们的例子中,它是 API 网关和 Lambda 函数。

template.yml

Resources:
    ApiGateway:
        Type: AWS::Serverless::Api
        Properties:
            StageName: Prod
            DefinitionBody:
                swagger: '2.0'
                info:
                    version: '1.0'
                    title: 'UserService'
                paths:
                    /createUser:
                        post:
                            responses: {}
                            x-amazon-apigateway-integration:
                                httpMethod: post
                                type: aws_proxy
                                uri:
                                    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${CreateUser.Arn}/invocations
                   /getUser:
                        post:
                            responses: {}
                            x-amazon-apigateway-integration:
                                httpMethod: post
                                type: aws_proxy
                                uri:
                                    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${GetUser.Arn}/invocations

    CreateUser:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: .
            Handler: index.create_user
            Runtime: nodejs10.x
    GetUser:
        Type: AWS::Serverless::Function
        Properties:
            CodeUri: .
            Handler: index.get_user
            Runtime: nodejs10.x

以下是我们看到的这种方法与您提到的其他两种方法相比的一些好处 -

  • 拥有单独的 Lambda 函数使我们能够拥有单独的 CloudWatch 日志,从而在出现问题时更容易进行调试。
  • 使用 SAM 模板(或 CloudFormation),可以更轻松地管理整个应用程序的发布过程。我们不必单独部署这些功能。
  • 可以更轻松地为不同的 Lambda 函数设置不同的监控规则、警报标准、通知。