반응형
안녕하세요. 남산돈가스입니다.
이번 포스팅에서는 웹을 개발하면서 가장 골칫거리지만 자주 쓰이게 될 수 있는 파일 업로드 기능 구현에 대해서 포스팅하려고합니다.
하지만 일반적인 파일업로드가 아닌, Lambda로 S3에 파일을 업로드 시키는 함수를 생성하고, 해당 Lambda함수를 API Gateway에 연결하여 multipart-form 형식으로 파일을 업로드하는 Serverless 파일업로드를 구현할 예정입니다.
이런 방식으로 업로드기능을 구현하게 되면, 추후에 어디든지 파일업로드 기능을 쓸 수 있는 Micro Service가 될 수 있습니다.
포스팅은 다음과 같이 3회에 걸쳐 진행되겠습니다.
#1. Lambda 함수 생성
#2. API Gateway, S3 셋팅
#3. API Gateway - Lambda 연결 및 테스트
그렇다면 지금부터 그 첫번째 단계인 Lambda 함수 생성을 진행해보겠습니다.
먼저 Lambda 서비스에 접속한 뒤 Node.js 기반의 새로운 함수를 생성합니다.
함수를 생성하면 아래와 같이 트리거가 추가되지 않은 날것의 함수가 생성된 것을 확인하실 수 있습니다.
쥐도 새도 모르게 변하는 AWS 콘솔 덕분에(?) 매번 포스팅할 때마다 Lambdad의 콘솔화면이 다채롭게 변하고있네요...ㅎㅎ
기존의 포스팅에서는 위 사진처럼 인라인으로 편집하는 포스팅만 진행했었는데 금번 포스팅에서는 외부 node_module을 사용하는 경우라 로컬에서 작업한 소스를 ZIP파일 형식으로 업로드하여 함수를 생성해보겠습니다.
- index.js
그리고 해당 함수에 필요한 node_module을 install 하기 위해서 npm install 명령어를 사용합니다.
필요 모듈
- aws-sdk : AWS javascript sdk 모듈
- parse-multipart : multipart형식으로 들어 온 파일을 데이터 형식으로 변환
- sha1 : 암호화 모듈
- bluebird : 비동기 Promise 패턴 매서드 사용 모듈
위의 모듈들을 npm install aws-sdk parse-multipart sha1 bluebird 명령어를 이용해 설치합니다.
gimseongsin-ui-MacBook-Pro:Desktop gimseongsin$ cd upload/
gimseongsin-ui-MacBook-Pro:upload gimseongsin$ npm install aws-sdk parse-multipart
sha1 bluebird
/Users/gimseongsin/Desktop/upload
├─┬ aws-sdk@2.163.0
│ ├─┬ buffer@4.9.1
│ │ ├── base64-js@1.2.1
│ │ ├── ieee754@1.1.8
│ │ └── isarray@1.0.0
│ ├── crypto-browserify@1.0.9
│ ├── events@1.1.1
│ ├── jmespath@0.15.0
│ ├── querystring@0.2.0
│ ├── sax@1.2.1
│ ├─┬ url@0.10.3
│ │ └── punycode@1.3.2
│ ├── uuid@3.1.0
│ ├── xml2js@0.4.17
│ └─┬ xmlbuilder@4.2.1
│ └── lodash@4.17.4
├── bluebird@3.5.1
├── parse-multipart@1.0.4
└─┬ sha1@1.1.1
├── charenc@0.0.2
└── crypt@0.0.2
npm WARN enoent ENOENT: no such file or directory, open '/Users/gimseongsin/Desktop/upload/package.json'
npm WARN upload No description
npm WARN upload No repository field.
npm WARN upload No README data
npm WARN upload No license field.
필요 모듈을 모두 설치하였다면, 앞서 생성한 index.js 에 아래와 같이 작성해줍니다.
(이후에 개인적으로 소스를 사용하신다면, 알맞게 수정하여 사용하시길 바랍니다.)
const AWS = require('aws-sdk');
const multipart = require("parse-multipart");
const s3 = new AWS.S3();
const sha1 = require('sha1');
const bluebird = require('bluebird');
exports.handler = function(event, context) {
let result = []
var bodyBuffer = new Buffer( event[ 'body-json' ].toString(), 'base64' );
var boundary = multipart.getBoundary( event.params.header[ 'Content-Type' ] )
var parts = multipart.Parse( bodyBuffer, boundary )
let files = getFiles( parts )
return bluebird.map( files, file => {
console.log( `uploadCall!!!` )
return upload( file )
.then(
data => {
result.push( { data, 'file_url': file.uploadFile.full_path } )
console.log( `data=> ${JSON.stringify( data, null, 2 )}` )
},
err => {
console.log( `s3 upload err => ${err}` )
}
)
})
.then(_=> {
return context.succeed(result)
})
}
let upload = function( file ) {
console.log( `putObject call!!!!` )
return s3.upload( file.params ).promise();
};
let getFiles = function( parts ) {
//let fileExt = 'png'
let files = [];
parts.forEach( part => {
let hash = sha1( new Buffer( new Date().toString() ) );
let buffer = part.data
let filePath = hash + '/';
let fileName = part.filename
let fileFullName = filePath + fileName;
let filefullPath = '버킷URL' + fileFullName;
let params = {
Bucket: '버킷명',
Key: fileFullName,
Body: buffer
};
let uploadFile = {
size: buffer.toString( 'ascii' ).length,
type: part.type,
name: fileName,
full_path: filefullPath
};
files.push( { params, uploadFile } )
} );
return files
}
index.js에 모든 소스를 작성했다면, 저장을 한 뒤 upload 폴더 하위에 있는
- index.js
- node_modules
들을 zip 형식으로 압축합니다.
압축 후 다시 Lambda 콘솔창으로 이동하여 코드입력유형을 zip파일 형식 업로드를 체크하시고 해당 zip 파일을 업로드 한 뒤 저장하시면 Lamba함수 생성은 모두 완료되었습니다.
이제 다음 포스팅에서 API Gateway 설정을 마치고 이번 포스팅에서 작성한 Lambda함수를 연결하여 파일업로드를 구현해보겠습니다.
감사합니다.
'Cloud > AWS' 카테고리의 다른 글
[AWS] 통합결제를 위한 조직에 계정 초대 (0) | 2020.04.17 |
---|---|
AWS Lambda - API Gateway로 S3 파일 업로드 API 만들기 #2 - API Gateway, S3 셋팅 (0) | 2020.04.17 |
[AWS] Amazon 통합결제와 대량구매할인 서비스 (0) | 2020.04.17 |
[AWS] Amazon Polly 한국어 서비스 지원 (0) | 2020.04.17 |
AWS API Gateway - HTTP 사용자 지정 통합을 사용하여 API 생성 (0) | 2020.04.17 |