이메일 수집 백엔드 만들기

Category
Review
Tags
Published
April 22, 2025
Last updated
Last updated April 22, 2025
 

이메일 수집

이메일 수집 백엔드를 만들어야 하는 이유를 말하자면 길지만, 짧게 말하자면 제품 검증을 위한 프리토타이핑을 시도하기 위해 랜딩페이지에서 고객의 이메일을 수집받아야 했다.
 
이때 프론트 랜딩페이지는 lovable, v0, cursor등으로 간단히 만들어낼 수 있었다.
그럼 여기에 이메일 수집을 추가해야하는데 프론트는 정적페이지로 배포할 예정임으로 따로 백엔드를 만들어야했다.
 

간단한 백엔드 제작

백엔드를 만드는건 어렵지 않았다. Django을 쓰던 Express을 쓰던 Spring을 쓰던, POST 요청을 받아 이메일을 저장하는 앱을 만드는건 누구나 할 수 있을 일이다. 문제는 단순히 이메일을 하나 받기에는 이 서버를 배포하기는 너무 큰 부담이 된다는 것이었다.
 
그렇다면 간단하게 만들려면 무엇을 써야할까? 바로 serverless가 생각났다. 이걸 제대로 사용해본적은 없지만 AWS의 lambda, api gateway, dynamodb를 사용해보면 0원에 가까운 비용(또는 0원)으로 백엔드를 제작할 수 있지 않을까?
 

DynamoDB

우선 DB를 만들기로 했다. 물론 간단히 POST요청을 로그로 남기는 것도 가능하겠지만, 별로 마음에 들지 않았다. 아무튼 백엔드의 꽃은 DB 아니겠는가?
 
notion image
다행히 DynamoDB는 무료로 사용할 수 있는걸로 보인다. 이메일을 25GB만큼 저장할일은 없을거라 생각이 들기에…
 
나중에 이상한 꼬투리를 잡아 요금이 발생할 수 있겠지만, 그건 그때 생각하고 우선 db를 만들어보자.
 
notion image
파티션 키는 site, 정렬 키를 email로 정했다. site는 디비를 재활용할 수 있게 만든것이다.
 
DB 설정은 기본 설정으로 진행했다.

Lambda

그다음은 람다로 이메일 수집 API를 만들어보자.
환경은 Node 22로, 코드는 아래와 같다
import AWS from 'aws-sdk'; const dynamoDB = new AWS.DynamoDB.DocumentClient(); const tableName = "emails"; const siteName = "hackathon"; // 여기에는 사이트 이름을 써주자. 그냥 아무 이름이나 써주면 된다. export const handler = async (event) => { console.log('Received event:', JSON.stringify(event, null, 2)); try { const { email } = event; if (!email || typeof email !== 'string' || email.trim() === '') { return { statusCode: 400, body: JSON.stringify({ message: '이메일 주소를 입력해주세요.' }), }; } // 간단한 이메일 형식 검사 (정규식은 필요에 따라 더 엄격하게) const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (!emailRegex.test(email)) { return { statusCode: 400, body: JSON.stringify({ message: '유효하지 않은 이메일 형식입니다.' }), }; } const params = { TableName: tableName, Item: { email: email.trim(), site: siteName, timestamp: new Date().toISOString(), // 수집 시간 기록 (선택 사항) }, ConditionExpression: 'attribute_not_exists(email)', // 중복 이메일 방지 (선택 사항) }; await dynamoDB.put(params).promise(); return { statusCode: 200, body: JSON.stringify({ message: '이메일 주소가 성공적으로 저장되었습니다.' }), }; } catch (error) { console.error('Error saving email:', error); let statusCode = 500; let message = '이메일 저장에 실패했습니다.'; if (error.code === 'ConditionalCheckFailedException') { statusCode = 409; message = '이미 등록된 이메일 주소입니다.'; } return { statusCode: statusCode, body: JSON.stringify({ message: message }), }; } };
 

aws-sdk 레이어 추가

놀랍게도 aws-sdk 라이브러리가 포함되어 있지 않음으로 이 라이브러리를 포함한 레이어를 추가해줘야한다.
 

Lambda 권한 설정

람다 함수에서, 구성 → 권한 → 역할 이름 클릭
notion image
 
IAM 역할(role)로 들어가서 정책(policy)를 연결해주자.
AmazonDynamoDBFullAccess를 연결해줘도 좋고, emails 테이블을 지정하는 정책을 만들어 연결해주어도 좋다.
notion image

API Gateway

notion image
notion image
notion image
 

CORS 설정

 
 

배포

API 배포를 눌러 배포해주자.
 
 

데이터 확인

 
 
DynamoDB에서 항목 탐색에 들어가자.
notion image
그럼 아래와 같이 무사히 데이터가 들어온 것을 확인할 수 있다.
notion image