Мы должны изменить способ обработки getObject запросы в наших приложениях Node.js AWS. Методы читаемого потока пригодятся, когда мы обрабатываем ответ S3.


1. Классическая проблема

Допустим, мы столкнулись с классической проблемой: у нас есть лямбда функция, которая программно получает объекты из S3 с SDK АМС в Node.js.

Приложение использует getObject метод для получения объекта из корзины.


2. Изменения

Но когда мы обновимся до версии 3 SDK (или напишем новое приложение с этой версией), мы испытаем некоторые изменения в сигнатуре метода.

Версия 3 является модульной, поэтому нам нужно установить в приложение только то, что нам нужно. Это уменьшит размер пакета, что сократит время развертывания, так что все звучит хорошо.

Мы должны установить только @aws-sdk/client-s3 модуль вместо всего aws-sdk упаковка. Модуль содержит getObject метод, который помогает нам получать объекты из корзины.

S3 конструктор по-прежнему доступен в модуле, поэтому на данный момент в нем нет ничего нового.


2.1. Нет метода обещания ()

Первое изменение заключается в том, что getObject метод вернет Promise.

В версии 2, getObject метод возвращает объект, и нам пришлось вызвать метод promise() метод, который разрешается в ответ S3. Поскольку мы всегда хотим использовать async/await синтаксис вместо обратных вызовов, promise() метод был частью нашей жизни развития.

Хорошая новость заключается в том, что AWS упростила подпись в версии 3, а getObject метод уже возвращает Promise. Поэтому нам не нужно вызывать promise() метод, если мы хотим await чтобы получить разрешенное значение.


2.2 Читаемые потоки вместо буфера

Обещание S3 getObject метод разрешается в объект, который расширяет GetObjectOutput тип. Этот объект имеет те же свойства, что и в SDK v2, но содержит критическое изменение.

В версии 3 Body свойство разрешенного объекта ответа S3 является читаемый поток вместо Buffer. Модификация подразумевает, что мы должны изменить то, как приложение обрабатывает объект.


3. Немного кода TypeScript

Читаемые потоки реализуют Symbol.asyncIterator метод, поэтому потоки также асинхронные итерации.

Таким образом, мы можем использовать for...of для перебора читаемого потока и получения фрагментов, предоставляемых потоком.

В следующем примере мы вернем объект, который мы загрузили с S3. Пример кода, который обрабатывает getObject запросы могут выглядеть так:

async function getObject(params) {
  const s3ResponseStream = (await s3.getObject(params)).Body
  const chunks = []

  for await (const chunk of s3ResponseStream) {
    chunks.push(chunk)
  }

  const responseBuffer = Buffer.concat(chunks)
  return JSON.parse(responseBuffer.toString())
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Каждый chunk это Buffer. После того, как мы получили последний фрагмент объекта S3, мы можем объединить и преобразовать их в строку, а затем, наконец, в объект JavaScript.

Обработчик Lambda может выглядеть так:

import { S3 } from '@aws-sdk/client-s3'

const s3 = new S3({ region: 'us-east-1' })

export async function handler(event) {
  try {
    const s3Object = await getObject({
      Bucket: 'ARN OF THE BUCKET',
      Key: 'NAME OF THE OBJECT TO FETCH',
    })

    return s3Object
  } catch (error) {
    console.error('Error while downloading object from S3', error.message)
    throw error
  }
}
Войти в полноэкранный режим

Выйти из полноэкранного режима

Мы можем обернуть логику обработки потока в функцию с именем getObjectи использовать его в try/catch block, как мы обычно делаем в обработчике Lambda.

Обратите внимание, что в приведенном выше примере мы по-прежнему храним объект S3 в памяти. Реальное преимущество потоков заключается в том, что мы обрабатываем блок по мере его поступления. Эти варианты использования, такие как преобразование данных, сохранение их в базе данных или возврат ответа в виде потока, не являются частью этого поста, и я могу рассказать о них в другой раз.


4. Резюме

getObject сигнатура метода изменилась в SDK версии 3. Body свойство ответа теперь является читаемым потоком вместо Buffer.

Мы можем использовать основную логику потока Node.js для обработки возвращаемого значения в наших функциях Lambda.


5. Ссылки

AWS SDK для JavaScript версии 3