BLOG
JavaScript용 AWS SDK에서 이벤트 스트림을 포함한 Amazon S3(Amazon Simple Storage Service) selectObjectContent API에 대한 지원을 발표하게 되어 기쁩니다. Amazon S3 Select를 사용하면 단순 SQL식을 사용하여 S3 개체에서 데이터의 하위 집합을 쿼리 할 수 있습니다.
Amazon S3는 한번에 전체 API 응답을 반환하는 대신 이벤트 시리즈로 응답을 스트리밍합니다. 이를 통해 응용 프로그램은 응답을 수신할 때 응답의 일부를 처리할 수 있습니다. 이러한 새로운 API 동작을 지원하기 위해, JavaScript용 AWS SDK는 응용 프로그램이 전체 응답을 기다릴 필요 없이 Node.js에서 이러한 이벤트를 비동기식으로 처리할 수 있도록 지원합니다. 브라우저 또는 React Native 런타임 환경에서 이러한 이벤트는 전체 응답이 수신된 후에 처리됩니다.
개체를 쿼리 하려면 Amazon S3 Select를 사용합니다.
Amazon S3 Select를 사용하면 간단한 SQL식을 사용하여 CSV 형식 또는 JSON 형식의 데이터가 포함된 개체를 쿼리 할 수 있습니다. 예를 들어, us-west-2 AWS 리전의 my-bucket이라는 버킷의 S3 개체에 업로드된 target-file.csv 이름을 가진 CSV 파일을 키로 사용하겠습니다.
CSV파일에는 일반적으로 구분된 사용자 이름 및 기간 목록이 포함되어 있습니다.
user_name,age
jsrocks,13
node4life,22
esfuture,29
…
이 CSV 파일을 통해 응용 프로그램이 20세 이상의 사용자만 선택하기를 원합니다. 이렇게 하려면 다음과 같은 SQL 식을 작성하여 20세 이상의 사용자에 대한 user_name 필드를 선택합니다.
SELECT user_name FROM S3Object WHERE cast(age as int) > 20
레코드를 선택하기 위해 Amazon S3 Select을 사용합니다.
이제 Amazon S3 SelectObjectContent API에서 JavaScript용 AWS SDK를 사용하여 Amazon S3에 저장된 JSON 및 CSV 파일에서 레코드를 선택할 수 있습니다.
먼저, my-bucket이 있는 AWS 리전을 위한 새로운 Amazon S3 클라이언트를 만들기를 원합니다. 이 클라이언트를 사용하여 selectObjectContent API 호출을 수행합니다.
const S3 = require(‘aws-sdk/clients/s3’);
const client = new S3({
region: ‘us-west-2’
});
selectObjectContent에 대한 JavaScript API용 AWS SDK 설명서를 따르면, API 요청 매개 변수는 사용하려고 하는 SQL 식에 대해 다음과 같이 보일 수 있습니다.
const params = {
Bucket: ‘my-bucket,
Key: ‘target-file.csv’,
ExpressionType: ‘SQL,
Expression: ‘SELECT user_name FROM S3Object WHERE cast(age as int) > 20’,
InputSerialization: {
CSV: {
FileHeaderInfo: ‘USE’,
RecordDelimiter: ‘\n’,
FieldDelimiter: ‘,’
}
},
OutputSerialization: {
CSV: {}
}
};
이제 API 호출을 위한 모든 준비가 완료되었습니다. 이벤트 처리 방법은 SDK가 실행되는 환경에 따라 달라집니다.
Node.js에서 스트림 사용하기
Node.js에서 이벤트가 도착할 때 스트림에서 이벤트를 읽어서 처리할 수 있습니다. 이를 위해 응답의 이벤트 스트림 멤버인 Payload는 읽을 수 있는 스트림 개체 모드입니다. 스트림이 개체 모드이기 때문에 개별 이벤트는 다운스트림 스트림으로 전송되거나 data 이벤트를 통해 방출됩니다. 이는 버퍼나 문자열을 방출하는 일반적인 스트림과는 다릅니다.
다음 예에서는 스트림을 사용하여 이벤트를 처리하고 오류를 처리하는 방법을 보여 줍니다.
s3.selectObjectContent(params, (err, data) => {
if (err) {
// Handle error
return;
}
// data.Payload is a Readable Stream
const eventStream = data.Payload;
// Read events as they are available
eventStream.on(‘data’, (event) => {
if (event.Records) {
// event.Records.Payload is a buffer containing
// a single record, partial records, or multiple records
process.stdout.write(event.Records.Payload.toString());
} else if (event.Stats) {
console.log(`Processed ${event.Stats.Details.BytesProcessed} bytes`);
} else if (event.End) {
console.log(‘SelectObjectContent completed’);
}
});
// Handle errors encountered during the API call
eventStream.on(‘error’, (err) => {
switch (err.name) {
// Check against specific error codes that need custom handling
}
});
eventStream.on(‘end’, () => {
// Finished receiving events from S3
});
});
브라우저에서 이벤트 읽기 및 React Native
브라우저와 React Native에서 SDK는 Amazon S3에서 전체 응답을 기다려야 이벤트를 처리할 수 있습니다. 이러한 환경에서 Payload 멤버는 Amazon S3에서 반환된 모든 이벤트를 포함하는 배열입니다.
s3.selectObjectContent(params, (err, data) => {
if (err) {
switch (err.name) {
// Check against specific error codes that need custom handling
}
return;
}
// data.Payload is a Readable Stream
const events = data.Payload;
for (const event of events) {
if (event.Records) {
// event.Records.Payload is a buffer containing
// a single record, partial records, or multiple records
process.stdout.write(event.Records.Payload.toString());
} else if (event.Stats) {
console.log(`Processed ${event.Stats.Details.BytesProcessed} bytes`);
} else if (event.End) {
console.log(‘SelectObjectContent completed’);
}
}
});
마지막 한마디
Amazon S3 Select를 사용하면 SQL 식을 생성하여 Amazon S3에 저장된 파일에서 CSV 또는 JSON 레코드의 하위 집합을 선택할 수 있습니다. JavaScript용 AWS SDK에서는 이 API를 사용하여 Node.js에서 비동기적으로 또는 브라우저 환경에서 동기적으로 이벤트를 처리할 수 있는 툴을 제공합니다.
원문 URL: https://aws.amazon.com/ko/blogs/developer/introducing-support-for-amazon-s3-select-in-the-aws-sdk-for-javascript/
** 메가존 TechBlog는 AWS BLOG 영문 게재글중에서 한국 사용자들에게 유용한 정보 및 콘텐츠를 우선적으로 번역하여 내부 엔지니어 검수를 받아서, 정기적으로 게재하고 있습니다. 추가로 번역및 게재를 희망하는 글에 대해서 관리자에게 메일 또는 SNS페이지에 댓글을 남겨주시면, 우선적으로 번역해서 전달해드리도록 하겠습니다.