최근 한 제조업체 회사의 웹사이트 리뉴얼을 외주로 맡아 혼자 개발을 진행했었다. 기존에 존재하던 웹사이트의 여러 문제점이 있지만, 가장 큰 목표는 웹사이트의 데이터를 비개발자도 쉽게 변경할 수 있게 하는 것이었다. IT 회사가 아니었기 때문에 회사에 개발자가 없어서 웹사이트의 데이터를 변경하는 데 어려움을 겪는 게 문제였다.
가장 흔한 해결책은 관리자 페이지를 만드는 것이다. 하지만 관리자 페이지를 만들려면 백엔드 개발이 필요해서 데이터베이스, 서버 및 각종 인프라 설정을 준비해야 했고, 사이트 규모에 비해 너무 큰 비용이라고 판단했다.
따라서 개발자가 아닌 회사 직원 누구나 데이터를 변경하고, 변경된 데이터가 웹사이트에 반영될 수 있도록 Headless CMS를 사용하여 개발을 해야겠다고 생각했다.
CMS는 Content Management System의 약자다. 말 그대로 디지털 콘텐츠를 관리하는 시스템이고, 이를 통해 회사의 콘텐츠를 제작, 편집 할 수 있게 된다.
전통적인 CMS(Traditional CMS)는 웹사이트의 백엔드와 프론트엔드를 모두 제어한다. 백엔드에 저장되는 데이터도 처리하고, 보여지는 페이지 레이아웃과 페이지 간 이동도 설정할 수 있다.
위 사진은 대표적인 CMS 중 하나인 Word Press의 소개이다. 웹사이트의 콘텐츠는 물론이고 보여지는 페이지까지 설정할 수 있게 하여, 프로그래밍 시간을 크게 줄여주고 개발적인 지식이 부족한 사람도 웹사이트를 제작하는 데 돕는다.
Headless CMS는 CMS인데 데이터만 신경쓰고 보여지는(프론트엔드) 형식은 신경쓰지 않는다. Headless 라는 단어에서 Head는 보여지는 프론트엔드를 말한다. 즉, Headless CMS는 프론트엔드가 없는 CMS를 말한다. 이는 CMS의 데이터를, 형식적인 틀에서 벗어나 프론트엔드 개발자의 입맛에 따라 다르게 데이터를 보여줄 수 있게 해준다.
그렇다면 Headless CMS로 관리되는 데이터를 어떻게 가져와서 보여줄까? Headless CMS에서는 프론트엔드에서 사용할 수 있는 API를 제공한다. 그렇다. 결국 Headless CMS는 백엔드 저장소고 프론트엔드에서는 API를 통해 이를 가져와 사용하기만 하면 된다. 좋은점은 Headless CMS에 데이터를 저장하기만 하면 별도의 인프라 설정이나 배포 과정없이 아주 쉽게 API로 원하는 데이터를 불러올 수 있다.
위 사진은 내가 사용했던 Headless CMS인 Sanity의 콘텐츠 편집 GUI인 Sanity Studio의 모습이다. 비개발자도 쉽게 콘텐츠를 편집하고 이를 통해 웹사이트의 데이터를 변경 할 수 있다.
위와 같이 Sanity의 쿼리 언어를 통해 api를 사용하여 원하는 데이터를 불러왔다. 페이지들을 SSG로 만들기 때문에 요청들을 캐싱했다.
그렇다면 요청들을 캐싱하고 모든 페이지들을 Static 하게 만들면, CMS의 데이터를 변경했을 때 어떻게 바로 변경사항을 보여줄까? 이는 Webhooks를 이용해 해결했다.
Webhooks란, 하나의 앱/웹이 다른 어플리케이션으로 앱관련 이벤트 정보를 실시간으로 제공하기 위한 방법이라고 할 수 있다. 이는 HTTP 요청을 통해 이루어진다. 쉽게 말해, 데이터가 변경 시 원하는 http 요청을 자동으로 보내주는 것이다.
첫 Webhook은 데이터가 변경됐을 때 캐시된 요청을 revalidate 해준다.
Next.js 13에서 캐시된 요청을 revalidate 하는 방식이 여러가지 있다. 나는 CMS의 데이터가 변경 됐을 때만 revalidate시키고 싶었다. 따라서 데이터 변경 시 Webhook을 이용해 Next.js 앱 라우트 핸들러 api로 요청을 보내고, 해당 요청이 들어오면 revalidatePath를 이용해 원하는 페이지의 데이터를 revalidate 시켰다.
모든 페이지들을 정적인 페이지지들로 만들고 싶었다. 따라서generateStaticParams를 활용해 dynamic routing 되는 페이지들까지 빌드시 정적인 페이지들로 만들어 주었다. 하지만 만약에 데이터가 추가됨에 따라 새로 생겨야 되는 페이지가 있어야 된다고 했을 때, 그 페이지를 정적으로 만들기 위해 새로 빌드를 해주어야 한다. 이를 위해 vercel의 deploy hooks를 사용하였다.
Deploy hooks란, 자동으로 빌드하고 배포를 하게 만드는 http 요청을 말한다. 설정된 주소로 http 요청을 보내면, 자동으로 다시 빌드를 하고 배포가 된다. 보이는 것 처럼 vercel의 공식문서에도 Headless CMS 콘텐츠 변경에 따른 자동 배포를 위해 deploy hooks를 사용할 수 있다고 한다.
배포한 vercel 프로젝트의 settings에서, 위와 같이 deploy hooks를 설정할 수 있다.
흐름을 다시 정리하면 다음과 같다:
-> Sanity의 데이터 업데이트
-> Webhooks를 통해 deploy hooks에 설정된 주소로 http 요청 전송
-> 자동으로 빌드 후 배포
정적인 웹사이트를 관리할 때 Headless CMS가 정말 간편하고 유용할 수 있다고 느꼈다. 특히 비개발자들도 웹사이트의 콘텐츠를 관리할 수 있다는 점이 정말 매력적이라고 생각한다.
다만 CMS는 데이터 변경이 즉각적이지 못해서 데이터 변경이 잦은 애플리케이션에는 적합하지 않을 거 같다.
역시 다양한 기술을 열린 마음으로 접한 뒤에, 사용 이유를 고민하고 신중하게 도입했을 때 좋은 결과가 있는 것 같다🤥