본문 바로가기
Cloud/AWS

json 파일 업로드/다운로드하는 API 만들기 : AWS API Gateway, Lambda, S3 사용

by 민휘 2023. 12. 24.

Upload

참고 자료

 

Role 생성

  • entity type : AWS service
  • use case : Lambda
  • policy : AmazonS3FullAccess, AmazonAPIGatewayInvokeFullAccess, CloudWatchFullAccess
  • role name : lambda-file-upload-s3-from-apigateway

 

Lambda 생성

  • author from scratch
  • function name : s3uploaderfromapidemo
  • runtime : Python 3.9
  • role : 아까 만든 role 선택

 

API Gateway 생성 및 Lambda 연결

API Gatway 생성

  • REST API 선택
  • new api
  • name : file-upload-api

 

루트 하위에 리소스 생성

  • resource name : bucket
  • resource path : {bucket}

 

bucket 하위에 리소스 생성

  • resource name : filename
  • resource path : {filename}

 

filename에 Method 생성

  • Method type : POST
  • Integration type : Lambda Function
  • 아까 생성한 람다 함수 선택
  • default timeout 활성화

 

method request의 Request body 설정

  • content type : application/json
  • name : Empty

 

integration request 설정

  • URL path parameter 추가
  • bucket : method.request.path.bucket
  • filename : method.request.path.filename

 

mapping template 추가

  • content-type : application/json
  • Generate template : Method Request passthroug

 

API Settings

  • Binary Media Types : / (이미지, 텍스트, pdf 등 대부분의 파일 형식 지원)

 

Deploy

  • new Stage : dev
  • invoke url 확인

 

Lambda 코드 작성

event 내용을 확인해보자. 람다 코드 작성 후 포스트맨에서 실행해본다. Body에 {"dfs":"ghgfd”} json을 실어 보냈다.

import json

def lambda_handler(event, context):
    return event

 

다음과 같은 결과가 나온다. body는 base64로 인코딩되었고, path param 정보도 포함하고 있다. 이 정보를 event에서 파싱해서 저장할 데이터와 저장할 위치를 결정한다.

{
    "body-json": "ewogICAgImRmcyI6ImdoZ2ZkIgp9",
    "params": {
        "path": {
            "bucket": "hwi-file-storage",
            "filename": "file-a.jpeg"
        },
        // ..
}

 

boto3 라이브러리를 이용해 s3 putObject api를 호출한다.

import json
import base64

import boto3
client = boto3.client('s3')

def lambda_handler(event, context):

    ms = base64.b64decode(event['body-json'])
    path = event['params']['path']
    bucket = path['bucket']
    filename = path['filename']

    print("bucket: ", bucket)
    print("filename: ", filename)


    response = client.put_object(
        Body=ms,
        Bucket=bucket,
        Key=filename,
    )

    print(response) # cloudwatch log

    return {
        'statusCode': 200,
        'body': json.dumps('%s is successfully saved!' % filename)
    }

 

 

postman 테스트

 

Download

 

 

Role 생성

  • entity type : AWS service
  • use case : Lambda
  • policy : AmazonS3FullAccess, AmazonAPIGatewayInvokeFullAccess, CloudWatchFullAccess
  • role name : lambda-file-download-s3-from-apigateway

 

Lambda 생성

  • author from scratch
  • function name : s3downloaderfromapidemo
  • runtime : Python 3.9
  • role : 아까 만든 role 선택

 

API Gateway에 Lambda 연결

 

filename에 메소드 생성

  • method type : GET
  • integration type : Lambda
  • lambda : 아까 만든 함수 선택
  • default timeout 활성화

 

integration request 설정

  • URL path parameter 추가
  • bucket : method.request.path.bucket
  • filename : method.request.path.filename

 

mapping template 추가

  • content-type : application/json
  • Generate template : Method Request passthrough

 

Lambda 코드 작성

import json

import boto3
client = boto3.client('s3')

def lambda_handler(event, context):
    path = event['params']['path']
    bucket = path['bucket']
    filename = path['filename']

    print("bucket: ", bucket)
    print("filename: ", filename)

    obj = client.get_object(Bucket=bucket, Key=filename)
    json_value = json.dumps(json.load(obj['Body']))

    return {
        'statusCode': 200,
        'body': json_value
    }

postman 테스트