Загрузка изображения в s3 из AWS Lambda с помощью NodeJS приводит к повреждению файла

#node.js #amazon-web-services #amazon-s3 #graphql

#node.js #amazon-веб-сервисы #amazon-s3 #graphql

Вопрос:

У меня есть бессерверное приложение (AWS), написанное на NodeJS, с открытой конечной точкой GraphQL и мутацией загрузки для загрузки изображения в корзину S3.

GraphQL lambda определяется следующим образом

 graphql:
  handler: src/functions/graphql/graphql.handler
  name: ${self:provider.stackName}-graphql
  events:
    - http:
        method: POST
        path: /graphql
  

GraphQL lambda — это в основном это

 const server = new ApolloServer({
  typeDefs,
  resolvers,
});

export const handler = server.createHandler();
  

У меня upload определена мутация

 type Mutation {
    uploadPhoto(file: Upload!, location: String): String!
}
  

И распознаватель выглядит так

 public async uploadPhoto(
    parent: any,
    params: { file: any; location: string }
  ): Promise<string> {
    const file = await params.file;

    const { createReadStream, filename, mimetype } = file;
    const { ext } = parse(filename);
    const uploadParams: S3.Types.PutObjectRequest = {
      Bucket: process.env.PHOTO_BUCKET,
      Key: `${params.location}/${randomNumber}${ext}`,
      ContentType: mimetype,
      Body: createReadStream(),
      ContentEncoding: "base64",
      ACL: "public-read",
    };
    try {
      console.log("upload params", uploadParams);
      const sendData = await this.s3bucket.upload(uploadParams).promise();
      console.log(sendData);
      return sendData.Location;
    } catch (error) {
      console.log("error uploading file", error);
      return error.message;
    }
  }
  

Также для того, чтобы API Gateway мог принимать двоичные данные, которые я установил

 custom:
  apigwBinary:
    types: 
      - image/jpeg
      - image/jpg
      - image/png

plugins:
  - serverless-apigw-binary
  

Тем не менее, после всего этого я могу загружать .txt файлы, например, но изображения выглядят примерно так https://cutt.ly/cg7zA6O так что похоже на пустой файл. Тип содержимого в порядке, размер файла также в порядке, но изображение повреждено.

Я предполагаю, что что-то в API Gateway неверно, но я не уверен на 100%

Комментарии:

1. Действительно ли ваш поток чтения создает данные в кодировке base64?

2. @jarmod он создает буфер, и когда я считываю поток в буфер, и buffer.toString("base64") я получаю строку, выглядящую примерно так « /VBORw0KGgoAAAANSUhEUgAAA1wAAAL9CAYAAAD9Iv39AAB4aUlEQVR4/f39W/01/f1g/RpMT1FAT/1HUkD9Qx39PEn9/f0X/f07PwMWSiX9H/39X/1oRv1//f1//f39AgAAAAD9/V8OAgAAAAAQLgAAAAAgXAAAAAAA/QUAAAAA …«Когда я пытаюсь проанализировать это как изображение, я получаю сообщение об ошибке, что это не изображение, а image/octet-stream

3. На самом деле это двоичный буфер cc @jarmod

4. Обычно вам не нужно кодировать. Создайте обычный ReadableStream для файла и предоставьте этот поток функции загрузки, если это возможно.

5. Это то, что я пытался сделать здесь Body: createReadStream() , но я не могу заставить его работать. Кроме того, это работает, например, для .txt, но не для изображений