Cloudflare Workers와 D1로 작은 블로그 운영하기

작은 블로그에 거대한 백엔드를 붙이면 기능보다 운영 부담이 먼저 커집니다. 하지만 반대로 모든 것을 정적 파일로 밀어 넣으면 댓글, 조회수, 관리자 편집처럼 운영에 필요한 기능을 넣기 어렵습니다. Workers와 D1 조합은 이 중간 지점에 잘 맞습니다.

Worker는 라우터이자 경계다

Worker의 역할은 단순히 HTML을 반환하는 것이 아닙니다. 정적 자산, 공개 API, 관리자 API, 동적 블로그 렌더링의 경계를 나누는 진입점입니다. /blog는 발행된 글만 읽고, /api/admin은 세션을 확인한 뒤 쓰기 작업을 수행해야 합니다. 이 경계가 흐려지면 작은 코드베이스도 금방 위험해집니다.

관리자 기능은 편의를 위해 만들지만, 공개 경로와 같은 사고방식으로 두면 안 됩니다. 인증, 입력 검증, 삭제 권한, 상태 값은 반드시 서버에서 다시 확인해야 합니다. 프런트엔드가 감춘 버튼은 권한 모델이 아닙니다.

D1은 애플리케이션 로그가 아니다

D1에 모든 이벤트를 세밀하게 넣고 싶어질 수 있습니다. 하지만 작은 블로그에서 필요한 것은 운영 판단에 충분한 데이터입니다. 글 본문, 댓글, 조회수, 일자별 방문자 정도면 대부분의 화면 요구를 만족합니다. 더 많은 데이터를 넣기 전에 그 데이터를 어디에 보여줄지 먼저 정해야 합니다.

조회수는 posts의 카운터로 충분할 수 있고, 방문자는 날짜와 익명 해시로 중복을 줄이면 됩니다. 정확한 분석 시스템이 아니라 운영 화면을 위한 지표라면 복잡도를 낮추는 쪽이 맞습니다.

단순함은 기능이 없다는 뜻이 아니다

작은 블로그도 운영하려면 마이그레이션, 세션, 백업, 에러 처리, 관리자 UI가 필요합니다. 차이는 이를 얼마나 얇게 유지하느냐입니다. Worker는 요청 경계를 담당하고, D1은 상태를 담당하며, 정적 자산은 디자인과 상호작용을 담당합니다.

이 구조의 장점은 실패 범위가 작다는 점입니다. 글 렌더링이 실패해도 정적 페이지는 살아 있고, 차트 조회가 실패해도 글 목록은 보여줄 수 있습니다. 작은 시스템일수록 이런 분리가 실제 운영 품질을 만듭니다.

실제 적용 메모

이 블로그는 Worker가 정적 파일과 동적 라우트를 같이 처리합니다. 구조는 단순하지만 경계는 명확해야 했습니다.

/                 -> index.html
/blog             -> D1에서 발행 글 읽어서 HTML 렌더링
/blog/:id         -> 글 상세, 조회수 증가
/api/blog/*       -> 공개 댓글 API
/api/admin/*      -> 관리자 세션 필요
/admin            -> 관리자 대시보드
/edit             -> 글 편집기

중요한 선택은 관리자 API를 공개 API와 분리한 것입니다. 댓글 삭제도 작성자 삭제와 관리자 삭제가 다릅니다. 작성자는 비밀번호 검증을 통과해야 하고, 관리자는 세션 검증을 통과해야 합니다.

또 하나는 대시보드 조회를 한 덩어리로 묶지 않은 것입니다. 방문자 그래프가 실패해도 글 목록과 인기 글 차트는 살아 있어야 합니다. 작은 시스템일수록 이런 실패 격리가 체감 품질을 만듭니다.

flowchart TD R[Request] --> W[Cloudflare Worker] W --> A[정적 Assets] W --> B[Blog HTML 렌더링] W --> C[Admin API] B --> D[(D1 posts)] B --> E[(D1 comments)] C --> F{Admin Session} F -->|valid| G[쓰기 작업] F -->|invalid| H[401]