Как обрабатывать двоичные данные из API Gateway в Lambda и наоборот? - PullRequest
1 голос
/ 18 апреля 2019

У меня сейчас есть следующие настройки: 1. S3 Bucket 2. API-шлюз с ресурсом GET / POST 3. Две лямбда-функции (одна для получения данных из s3, одна для хранения данных в s3)

Например, GET Resource, я передаю ключевой параметр, который используется в лямбда-функции для получения объекта из корзины s3.затем я хочу вернуть полученный объект на шлюз API и клиенту в виде двоичного файла.

В ресурсе POST я хочу отправить двоичную полезную нагрузку, например: pdf или zip-файл, сохранить его в s3 ивернуть сгенерированный ключ.

Так что, с одной стороны, я хочу, чтобы мои API-шлюз и лямбда могли возвращать двоичные данные в GET-запросе, с другой стороны, я хочу, чтобы он принимал двоичную полезную нагрузку в POST-запросе.

В настройках API-шлюза я установил Binary-Media-Types на application/octet-stream.Также у меня активирована лямбда-прокси-интеграция.

Мой вопрос: как я могу обрабатывать двоичные данные в API-шлюзе / лямбде?

Я пытался возиться с заголовками и типами содержимого, но более или менеея не знал, что я делал: (

Пример лямбды для хранения багажа для хранения данных из запроса POST в S3

import boto3
import json
import uuid
import logging
from botocore.exceptions import ClientError

def lambda_handler(event, context):

    #data = <binary data from POST request>?

    logger = logging.getLogger()
    logger.setLevel(logging.INFO)

    bucket = 'bucket1'

    uniqueid = str(uuid.uuid4())
    logger.info("Generated UUID: " + uniqueid)

    s3 = boto3.resource('s3')

    logger.info("Trying to save file '" + uniqueid + "' to bucket '" + bucket + "'")

    savedObj = None

    try:
        savedObj = s3.Bucket(bucket).put_object(Key=uniqueid, Body=<here should be my binary payload from POST request>)
    except ClientError as e:
        logger.error("Saving of object has failed: " + str(e.response['Error']['Message']))

    if savedObj is None:
        return {
            'statusCode': 500,
            'body': json.dumps({
                'message': 'Saving of object has failed!'
            })
        }

    return {
        'statusCode': 200,
        'body': json.dumps({
            'token': uniqueid
        })
    }

лямбда для получения багажа для получения объекта из s3 по заданномуключ и возврат двоичной полезной нагрузки в ответе

import boto3
import json
from pprint import pprint
from botocore.exceptions import ClientError
import logging

def lambda_handler(event, context):

    logger = logging.getLogger()
    logger.setLevel(logging.INFO)

    bucket = 'bucket1'
    token = event["queryStringParameters"]["token"]

    s3 = boto3.client('s3')

    objectFromS3 = None

    try:
        objectFromS3 = s3.get_object(Bucket=bucket, Key=token)
    except ClientError as ex:
        if ex.response['Error']['Code'] == 'NoSuchKey':
            logger.info('No object found - returning empty')
        else:
            raise ex

    if objectFromS3 is None:
        return {
            'statusCode': 404,
            'body': json.dumps({
                'message': 'Cannot retrieve object from storage!'
            })
        }

    pprint(objectFromS3)
    #ContentType application/octet-stream

    return {
        'statusCode': 200,
        'body' : <binary data from retrieved s3 object here?>,
        'headers': {
            'content-type': 'application/octet-stream'
        },
        'isBase64Encoded': True
    }

Я ожидал получить двоичную полезную нагрузку в ответе GET и ожидал, что API-шлюз передаст двоичную полезную нагрузку от запроса POST к лямбде, но ничего из этого не было достигнуто с тем, что я пробовал.

Надеюсь, я достаточно хорошо описал свою проблему, если потребуется какое-либо разъяснение, дайте мне знать.

С наилучшими пожеланиями, aws noob

Ответы [ 2 ]

2 голосов
/ 27 мая 2019

Во-первых, вам нужно настроить типы MIME, которые вы собираетесь обрабатывать как двоичные данные в настройках шлюза API.

Настройки -> Бинарные типы носителей.

Укажите точный тип MIME для использования в качестве приложения двоичных данных / pdf, application / zip и т. Д. Application / octet-stream представляет общие данные, точный тип которых неизвестен.

В вашем запросе Http должен быть заголовок Accept , указывающий, какой тип MIME входит в полезную нагрузку.

  • Принимаем: заявка / pdf

  • Принимаем: приложение / почтовый индекс

Поскольку процесс обработки запросов и ответов AWS Lambda выполняется в кодировке base64, необходимо декодировать тело запроса POST и получать исходный двоичный контент перед загрузкой в ​​корзину S3.

После извлечения данных из корзины S3 лямбда-кодирование двоичных данных перед отправкой их на шлюз API. В ответ вы должны установить значение флага isBase64Encoded в True. Затем API-шлюз выполняет декодирование Base64 над закодированными данными перед отправкой их клиенту , если запрос Http включает соответствующий заголовок Accept .

0 голосов
/ 28 мая 2019

получить камеру:

Если ваш файл уже находится в S3, вы можете перенаправить пользователя на ссылку на файл в S3, добавив атрибут Location в заголовки API-шлюза, уменьшив трафик данных шлюза.

пример:

exports.handler = (event, context, callback) => {
  return callback(null, {
    statusCode: 301,
    headers: {
      Location: 'https://<...S3...>',
    }
  });
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...