Какие дополнительные поля включает AWS Amplify API при вызове лямбда-функции? - PullRequest
0 голосов
/ 07 мая 2020

У меня есть эта AWS лямбда-функция для создания объекта заметки в моей таблице 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"
    }
  }
}

Однако, когда я вызываю эту функцию Lambda с запросом POST через API aws-amplify, я определяю только поле body в объекте init, т.е.

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

, что приводит к следующим вопросам ...

  • Как получила ли функция Lambda необходимое поле requestContext из вызвавшего ее метода aws-amplify API POST?
  • Было ли оно добавлено к объекту init API aws-amplify?

Это был бы очевидный ответ, но это приводит меня к другому вопросу ...

  • Какие еще поля добавляются к объекту init API aws-amplify?

1 Ответ

0 голосов
/ 08 мая 2020

Объект 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"
    }
  }
}
...