首页 > 解决方案 > 调用 Lambda 函数时,AWS Amplify API 包括哪些额外字段?

问题描述

我有这个 AWS Lambda 函数可以在我的 DynamoDB 表中创建一个注释对象:

import * as uuid from "uuid";
import AWS from "aws-sdk";

const dynamoDb = new AWS.DynamoDB.DocumentClient();

export function main(event, context, callback) {
  // Request body is passed in as a JSON encoded string in 'event.body'
  const data = JSON.parse(event.body);

  const params = {
    TableName: process.env.tableName,
    // 'Item' contains the attributes of the item to be created
    // - 'userId': user identities are federated through the
    //             Cognito Identity Pool, we will use the identity id
    //             as the user id of the authenticated user
    // - 'noteId': a unique uuid
    // - 'content': parsed from request body
    // - 'attachment': parsed from request body
    // - 'createdAt': current Unix timestamp
    Item: {
      userId: event.requestContext.identity.cognitoIdentityId,
      noteId: uuid.v1(),
      content: data.content,
      attachment: data.attachment,
      createdAt: Date.now()
    }
  };

  dynamoDb.put(params, (error, data) => {
    // Set response headers to enable CORS (Cross-Origin Resource Sharing)
    const headers = {
      "Access-Control-Allow-Origin": "*",
      "Access-Control-Allow-Credentials": true
    };

    // Return status code 500 on error
    if (error) {
      const response = {
        statusCode: 500,
        headers: headers,
        body: JSON.stringify({ status: false })
      };
      callback(null, response);
      return;
    }

    // Return status code 200 and the newly created item
    const response = {
      statusCode: 200,
      headers: headers,
      body: JSON.stringify(params.Item)
    };
    callback(null, response);
  });
}

它的作用与问题无关。这里需要注意的重要一点是,它可以通过命令serverless invoke local --function create --path mocks/create-event.json和示例事件成功离线执行create-event.json

{
  "body": "{\"content\":\"hello world\",\"attachment\":\"hello.jpg\"}",
  "requestContext": {
    "identity": {
      "cognitoIdentityId": "USER-SUB-1234"
    }
  }
}

但是,当我通过 API 使用 POST 请求调用这个 Lambda 函数时aws-amplify,我只在对象中定义了一个body字段init,即

import { API } from "aws-amplify";
...
function createNote(note) {
  return API.post("scratch-notes", "/scratch-notes", {
    body: note
  });
}

这导致以下问题......

那将是显而易见的答案,但这使我想到了另一个问题……

标签: javascriptaws-lambdaserverless-frameworkaws-amplifyaws-serverless

解决方案


event对象还包含两个额外的结构,afaik:一个requestContext对象和一个pathParameters对象。

requestContext对象只是出于测试目的和我们一般的方便而context包含在对象中的对象。event

pathParameters对象是从带有特殊标记的路径中提取的字段列表。

  get:
    handler: get.main
    events:
      - http:
          path: scratch-notes/{id}
          method: get
          cors: true
          authorizer: aws_iam

像这样的处理程序会接受一个带有 URI 的请求scratch-notes/1234并返回一个pathParameters对象,如下所示:

{
  "pathParameters": {
    "id": "1234"
  }
}

当然,这两个对象可以结合使用无服务器框架离线调用我们的 API,如下所示:

{
  "pathParameters": {
    "id": "59747e00-8e61-11ea-8cb8-5d9bcedbe6f4"
  },
  "body": "myBody",
  "requestContext": {
    "identity": {
      "cognitoIdentityId": "USER-SUB-1234"
    }
  }
}

推荐阅读