Relay API 설계: Cloudflare Workers로 메일 전송 기반을 구축
이 페이지는 일본어 원문을 기계 번역한 것입니다. 일본어 원문 보기
1. 왜 외부 메일 제공업체인 API를 사용하지 않았는가
메모를 이메일로 전송하는 앱을 만들 때 가장 먼저 떠오르는 것은 대형 메일 제공업체의 전송 API입니다. 하지만 개인 개발자에게는 Google OAuth 심사의 장벽이 매우 높았습니다.
Google OAuth 심사를 통과하지 않은 앱에는 “이 앱은 Google에서 확인되지 않았습니다”라는 경고 화면이 표시됩니다. 메모 앱에게 이 경고는 치명적입니다. 사용자는 자신의 생각과 개인 정보를 메모로 전송합니다. 그 첫 번째 경험에서 “검증되지 않았습니다”라는 메시지가 표시되면, 누가 이 앱을 신뢰할까요?
Google OAuth 심사 신청 절차는 개인 개발자에게 험난한 길입니다. 개인정보 보호정책 준비, 범위의 정당성 설명, 보안 평가—대기업 팀이라면 그렇지만, 혼자 개발하는 앱에게는 메일 전송이라는 단일 기능을 위해 지불하는 비용이 너무 큽니다.
필요했던 것은 OAuth 심사의 복잡함 없이, 사용자의 신뢰를 손상시키지 않고 이메일을 전송할 수 있는 솔루션이었습니다. 그 답은 자체 Relay API입니다.
2. Cloudflare Workers + Resend API 아키텍처
Relay API의 아키텍처는 단순하면서도 견고합니다. iOS 앱으로부터 요청을 받아 메일 전송 서비스에 중계합니다—그것만을 위해 특화된 설계입니다.
Cloudflare Workers는 전 세계의 엣지 위치에서 TypeScript 코드를 실행하는 서버리스 플랫폼입니다. Cloudflare의 설명에 따르면, isolate라는 가벼운 실행 환경에서 코드를 실행하기 때문에 가상 머신형 서버리스에서 발생하는 콜드 스타트가 없습니다.
Resend API는 현대적인 이메일 전송 서비스입니다. SPF/DKIM/DMARC를 설정하기 쉽고, TypeScript에서 쉽게 호출할 수 있습니다.
비용 측면에서는 Cloudflare Workers의 무료 플랜은 1일 100000 요청까지이며, Resend의 무료 플랜은 1일 100통·월 3,000통까지 사용할 수 있습니다(2026년 10월 기준 각사의 요금 페이지). 작게 시작하여 전송량에 맞춰 유료 플랜으로 전환할 수 있는 구성입니다.
3. 이메일 주소 검증(6자리 코드 방식)
Relay API는 검증된 이메일 주소로만 메모를 전송합니다. 이는 악용 방지를 위한 가장 기본적인 방어층입니다.
메모 전송을 시작하기 전에, 전송 대상 이메일 주소를 검증하는 흐름이 필요합니다.
- 사용자가 앱에 이메일 주소를 입력합니다
- Relay API가 6자리 검증 코드를 해당 주소로 전송
- 사용자가 수신한 6 자리 코드를 앱에 입력
- 검증이 완료되었습니다. 이후, 해당 이메일 주소로 메모 전송이 허용됩니다
이 메커니즘을 통해 타인의 이메일 주소로 무단으로 메모가 전송되는 것을 방지합니다. 검증 코드는 해당 주소의 수신함에 도착하므로, 수신함을 확인할 수 없는 사람은 해당 주소를 수신지로 확인할 수 없습니다.
검증은 이메일 주소당 한 번만 가능합니다. 검증이 한 번 완료되면, 이후에는 코드 입력 없이 메모를 계속 전송할 수 있습니다.
4. 다층 레이트 제한 구현
메일 전송 API의 악용을 방지하기 위해 여러 레이어에서 속도 제한을 구현하고 있습니다.
const RATE_LIMITS = {
devicePerMinute: 30,
devicePerDay: 200,
ipPerHour: 120,
globalPerDay: 300,
};
카운터는 Cloudflare KV에 저장되며, 각 시간 창마다 리셋됩니다. 일반적인 전송은 통과하면서, 불법적인 대량 접근을 억제합니다.
5. 멱등성: 동일한 메모를 이중으로 전송하지 않기 위한 설계
네트워크 통신에는 불확실성이 따릅니다. 전송 버튼을 누른 후 응답이 돌아올 때까지 통신이 끊기는 경우가 있습니다. 앱은 타임아웃으로 판단하여 재전송을 시도하지만, 실제로 최초 요청은 서버에 도착해 있었습니다——흔한 시나리오입니다.
이 경우에는 멱등성(idempotency)으로 준비합니다.
- 각 메모에 고유한 UUID(메시지 ID)를 부여합니다
- Relay API는 해당 메시지 ID를 메일 전송 서비스(Resend)에 대한 요청의 멱등키(Idempotency-Key)로 전달합니다
- Resend은 동일한 키를 24시간 동안 기억하고 있으며, 동일한 내용의 요청이 다시 오면 이메일을 보내지 않고 이전과 동일한 응답을 반환합니다
- 앱에는 성공 응답이 반환됩니다(2회차도 1회차와 동일한 응답)
이 설계에 따라 네트워크가 불안정하고 재시도가 발생하더라도 24 시간 동안 동일한 메모가 중복 전송되지 않습니다(Resend이 키를 기억하고 있는 기간). 그 이후의 재송송은 구분할 수 없으므로, 중복을 중단할 수 있는 것은 이 기간 내에 있습니다.
6. 에지 컴퓨팅의 장점
Cloudflare Workers를 메일 전송 기반으로 채택한 가장 큰 이유는 엣지 컴퓨팅의 본질적인 장점에 있습니다.
메모 앱에게 이 조합은 다루기 쉬운 선택이었습니다. 이용자에 가까운 거점에서 처리가 시작되고, 서버 관리가 필요 없으며, 작은 규모라면 비용도 절감할 수 있습니다. 그것이 엣지 컴퓨팅에서 릴레이 API를 만든 이유입니다.
이 기술 기반 위에 구축된 “SimpleMemo”을 꼭 사용해 보시기 바랍니다.
App Store에서 다운로드자주 묻는 질문
Q. 왜 Cloudflare Workers를 선택하셨나요?
가상 머신형 콜드 스타트가 없고, 이용자에 가까운 거점에서 처리할 수 있으며, 소규모라면 무료 플랜부터 시작할 수 있기 때문입니다.
Q. 이메일 도달률은 어떻게 되나요?
발신자 도메인에는 SPF·DKIM·DMARC를 설정하고 있습니다. 그럼에도 불구하고, 수신자 메일 서비스의 판단에 따라 스팸 메일로 분류될 수 있습니다. 도착하지 않을 경우, 스팸 메일 폴더와 수신 주소 확인이 완료되어 있는지 확인해 주세요.
Q. 서버에 메모 내용이 저장됩니까?
Relay API는 통과형입니다. 메모 내용을 지속적으로 저장하지 않습니다. 전송 처리에 필요한 범위 내에서만 일시적으로 처리합니다.
Q. 환율 제한에 걸리면 어떻게 됩니까?
메모는 단말기의 전송 대기(Outbox)에 남아 있으며, 회선 복구·앱을 열었을 때·백그라운드 처리를 계기로 자동으로 다시 전송됩니다(자동 재전송에는 횟수에 제한이 있습니다).
관련 기사
참고문헌
- Cloudflare Workers Documentation — 릴레이 API의 서버리스 실행 기반. 에지에서 요청 처리에 사용
- RFC 5321 — Simple Mail Transfer Protocol (SMTP) — 메일 전송 기본 프로토콜 사양. 릴레이 API가 준수하는 SMTP 표준
- RFC 6376 — DomainKeys Identified Mail (DKIM) — 전송 메일의 변조 방지 및 발신자 인증에 사용되는 전자 서명 사양
- RFC 7208 — Sender Policy Framework (SPF) — 송신 도메인 인증. 허용된 IP 주소에서의 메일 전송을 검증
- Resend API 문서 — 메일 전송 API 프로바이더. Cloudflare Workers에서 호출하는 메일 전송 서비스