设计无服务器功能与常规服务器的差异

Differences in designing a serverless function vs. regular server

我想知道在设计无服务器功能时采用什么方法,同时以设计常规服务器作为参考点。

对于传统的服务器,人们会专注于定义集合,然后可以对每个集合进行 CRUD 操作 运行(HTTP 动词,例如 GET 或 POST)。 例如,您将有一个 users 的集合,您可以通过 app.get('/users', ...) 获取所有记录,通过 app.get('/users/{id}', ...) 获取特定记录或通过 app.post('/users', ...).[=21 创建一个=]

您设计无服务器功能的方法有何不同?具体来说:

  1. 区分 HTTP 操作是否有意义,还是您会选择 POST?我发现在客户端定义它们很有用,可以决定在出现错误时是否要重试(如果操作是幂等的,重试是安全的等等),但这似乎并不重要后端。
  2. 命名。我假设你会使用像 getAllUsers() 这样的东西,当你使用常规服务器时你会定义 users 的集合,然后只使用 GET 来指定你想用它做什么。
  3. 功能规模:如果您需要一步在后端做很多事情。你会定义一些小函数,比如 lookupUser()endTrialForUser()(如果我们从 lookupUser() 得到的用户试用时间超过 7 天则触发)等等然后 运行 他们一个接一个地从客户端(决定是否应该在客户端结束试用 - 看起来很不安全),或者你会创建一个 getUser() 然后处理那里的所有逻辑吗?
  4. 路由。在无服务器函数中,我们不能真正做 .../users/${id}/accountData 之类的事情。您将如何获取嵌套数据?你每次 return 一个完整的 JSON 好吗?

我一直在寻找关于此事的一些综合文章,但没有找到。有什么建议吗?

这是您提出的一个非常宽泛的问题。让我试着逐点回答。

首先,您在这里谈论的方法是 Serverless API 项目方法。您可以克隆他们的示例项目,以更好地了解如何构建 REST api 来执行 CRUD 操作。从 installing the SAM cli 开始,然后 运行 以下命令。

$ sam init
Which template source would you like to use?
    1 - AWS Quick Start Templates
    2 - Custom Template Location
Choice: 1

Cloning from https://github.com/aws/aws-sam-cli-app-templates

Choose an AWS Quick Start application template
    1 - Hello World Example
    2 - Multi-step workflow
    3 - Serverless API
    4 - Scheduled task
    5 - Standalone function
    6 - Data processing
    7 - Infrastructure event management
    8 - Machine Learning
Template: 3

Which runtime would you like to use?
    1 - dotnetcore3.1
    2 - nodejs14.x
    3 - nodejs12.x
    4 - python3.9
    5 - python3.8
Runtime: 2

Based on your selections, the only Package type available is Zip.
We will proceed to selecting the Package type as Zip.

Based on your selections, the only dependency manager available is npm.
We will proceed copying the template using npm.

Project name [sam-app]: sample-app

    -----------------------
    Generating application:
    -----------------------
    Name: sample-app
    Runtime: nodejs14.x
    Architectures: x86_64
    Dependency Manager: npm
    Application Template: quick-start-web
    Output Directory: .
    
    Next steps can be found in the README file at ./sample-app/README.md
        

    Commands you can use next
    =========================
    [*] Create pipeline: cd sample-app && sam pipeline init --bootstrap
    [*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
针对您的问题提出要点:
  1. 是的,您应该将您的 HTTP 操作与其合适的 HTTP verbs 区分开来。这可以在 API 网关配置,并且可以在 Lambda 代码中检查。检查处理程序的源代码和您刚刚使用 SAM.
  2. 克隆的项目中的 template.yml 文件
   // src/handlers/get-by-id.js
   if (event.httpMethod !== 'GET') {
        throw new Error(`getMethod only accepts GET method, you tried: ${event.httpMethod}`);
   }
   # template.yml
   Events:
       Api:
         Type: Api
         Properties:
           Path: /{id}
           Method: GET
  1. 命名完全由开发者决定。您可以采用与常规服务器项目相同的方法。 您可以使用名称 getAllUsersusers 定义处理程序,然后在 AWS API Gateway 中将该资源的路径设置为 GET /users。您可以选择您想要的HTTP verbs。查看这个教程以获得更好的理解。

  2. 再次由您决定。您可以创建一个单独的 Lambda 来处理所有这些逻辑,或者创建由客户端根据前一个 API 的响应一个接一个地触发的单独的 Lambda。我会说,创建一个 Lambda 和 return 累积响应以减少请求数量。但同样,这完全取决于 UI 集成。如果您的屏幕需要单独的 API 调用,那么请务必创建单独的 lambda。

  3. 这不是真的。我们可以在 API 网关中指定动态路由。 在 API 网关中设置路由时,您可以使用 {variableName} 轻松地在路由中设置通配符。

    GET /users/{userId} userId 然后可以通过 event.pathParameters.

    在 lambda 函数中使用

    GET /users/{userId}?a=x 同样,您甚至可以传递查询字符串并通过代码中的 event.queryStringParameters 访问它们。看看 working with routes.

我为您推荐的教程:

Tutorial: Build a CRUD API with Lambda and DynamoDB