LY Corporation Tech Blog

LY Corporation과 LY Corporation Group(LINE Plus, LINE Taiwan and LINE Vietnam)의 기술과 개발 문화를 알립니다.

This post is also available in the following languages. English

전통적인 CMS에서 LandPress Content로 CMS를 옮기는 이유

LINE에서는 3년 전 기존 헤드리스 CMS의 구조와 성능을 개선한 새로운 헤드리스 CMS, LandPress Content를 사내 임직원 대상으로 출시했습니다. 그 후 전통적인 CMS를 사용하던 여러 LINE 서비스가 LandPress Content로 재개발되기 시작했는데요. 이번 글에서는 전통적인 CMS에서 헤드리스 CMS로 마이그레이션할 때 주의해야 할 점과 마이그레이션 후 어떤 점이 개선됐는지 살펴보겠습니다.

헤드리스 CMS가 등장한 배경

먼저 헤드리스 CMS가 등장한 배경을 살펴보겠습니다. 

전통적인 CMS의 문제점

전통적인 CMS는 아래와 같이 프런트엔드와 백엔드가 결합된 구조로 한 몸처럼 작동합니다. 대표적으로 WordPress와 Movable Type이 있습니다. 

전통적인 CMS 구조

'프런트엔드와 백엔드를 함께 제공하다니 정말 편리하겠군요!'라고 생각하실 수 있는데요. 사실 사이트를 운영할 때 이와 같은 모놀리식(monolithic) 구조는 다음과 같은 다양한 문제를 야기합니다.

  • 성능과 보안: 모놀리식 구조는 용량이 크고 컴퓨팅 자원을 많이 소모하기 때문에 성능이 떨어지고 최적화하기 어렵습니다. 또한 보안 관점에서 공격 대상이 될 수 있는 노출 영역이 커서 플러그인 등에서 보안 이슈가 빈번히 발생하기도 합니다.
  • 개발자 경험: 프런트엔드와 백엔드가 강하게 결합돼 있는 구조 때문에 새로운 기술을 적용하거나 확장하기 어렵습니다. 표준처럼 자리 잡은 현대적인 프레임워크를 적용하는 것도 불가능하며, 유지 보수 비용도 증가합니다.
  • 사용자 경험: 전통적인 CMS를 사용하면 사용자는 콘텐츠 관리 외에도 신경 써야 할 것이 많습니다. 불필요한 기능이나 구성 때문에 발생하는 이슈들을 관리하느라 에너지가 낭비되는 경우가 빈번히 발생합니다.

헤드리스 CMS란

이와 같은 전통적인 CMS의 문제를 보완하기 위해 헤드리스 CMS가 등장했습니다. 헤드리스 CMS는 머리가 없는 CMS로, 여기서 머리는 프런트엔드를 의미합니다. 헤드리스 CMS는 프런트엔드 계층이 CMS에서 분리돼 있고, 프런트엔드와 백엔드가 API를 통해 통신합니다.

헤드리스 CMS 구조

이런 헤드리스 CMS 구조는 모놀리식 구조에서 발생하던 여러 문제를 해결할 수 있습니다.

  • 성능과 보안: 프런트엔드와 백엔드가 분리돼 있어서 훨씬 수월하게 성능을 최적화할 수 있고, 보안 이슈를 효과적으로 예방하고 그에 대응할 수 있습니다.
  • 개발자 경험: 프로젝트나 개발자의 성향에 맞춰 개발 플랫폼이나 개발 언어를 자유롭게 선택할 수 있고, 새로운 기술에 대응할 수 있습니다.
  • 사용자 경험: 콘텐츠 관리자가 콘텐츠 관리에만 집중할 수 있습니다. 

LINE의 헤드리스 CMS, LandPress Content 출시

LINE에서는 LandPress Content라는 헤드리스 CMS를 직접 개발해서 사내 임직원을 대상으로 운영하고 있습니다. 앞서 살펴본 헤드리스 CMS의 여러 장점 덕분에 기존에 전통적인 CMS로 론칭했던 많은 서비스가 LandPress Content로 재개발되고 있으며, 자연스럽게 데이터 마이그레이션 니즈가 발생했습니다.

또한 LY Corporation 출범 이후 LINE과 Yahoo! JAPAN이 사내 플랫폼을 공유하게 되면서 2022년부터 Movable Type을 LandPress Content로 마이그레이션하고 싶다는 요청이 많이 들어오고 있습니다. 이에 따라 'Movable Type 사용자를 위한 LandPress Content 마이그레이션 도구를 만들면 어떨까?'라는 생각이 들어서 마이그레이션 도구를 개발하기 시작했습니다.

전통적인 CMS에서 LandPress Content로 마이그레이션

LandPress Content로 마이그레이션하는 도구를 어떻게 개발했는지 단계별로 살펴보겠습니다. 

데이터 구조 파악

Movable Type을 LandPress Content로 마이그레이션하기 위해서는 먼저 Movable Type과 LandPress Content의 구조와 각 구조의 차이를 이해해야 합니다. 아래 그림은 Movable Type과 LandPress Content의 구조를 간략하게 비교한 것입니다. 가장 눈에 띄는 차이는 '데이터 구조가 고정돼 있는지, 아니면 데이터 구조를 사용자가 직접 만드는지'입니다.

Movable Type 데이터 구조
LandPress Content 데이터 구조

Movable Type의 구조

Movable Type에는 Site 하위에 Article과 Page라는 고정 컬렉션이 있습니다. Article과 Page는 고정된 필드와 커스텀 필드로 구성되며, 각각 아이템을 분류하기 위해 사용하는 Category와 Folder가 있습니다. 이해를 돕기 위해 Movable Type에서 Article과 Page 컬렉션에 아이템을 추가하는 화면을 가져왔습니다. 

Article과 Page 컬렉션에 아이템을 추가하는 화면

LandPress Content의 구조

LandPress Content의 구조는 어떨까요? LandPress Content는 Project 하위에 고정된 컬렉션과 필드가 없기 때문에 사용자가 원하는 컬렉션 유형과 필드 유형을 선택해 데이터 구조를 구성할 수 있습니다. 아래는 LandPress Content 컬렉션에 아이템을 추가하는 화면입니다. 사용자가 목적에 맞게 직접 컬렉션 타입과 필드 타입을 구성해 아이템을 추가할 수 있습니다.

블로그를 위한 Collection 타입 컬렉션을 만든 후 아이템을 추가하는 화면
메인 페이지를 위한 Single 타입 컬렉션을 만든 후 아이템을 추가하는 화면
FAQ를 위한 Collection 타입 컬렉션을 만든 후 아이템을 추가하는 화면

데이터 매칭

이제 서로 구조가 다른 Movable Type과 LandPress Content 데이터를 어떻게 매칭했는지 살펴보겠습니다. 기존 Movable Type 데이터를 LandPress Content에서도 편리하게 사용할 수 있도록 다음과 같이 매칭 구조를 설계했습니다.

Movable Type과 LandPress Content 매칭 구조

구조를 설계하면서 특별히 신경 쓴 부분은 다음과 같습니다.

  • Movable Type의 필드 타입을 LandPress Content의 필드 타입으로 적절히 매칭합니다.
  • Movable Type의 Category와 Folder를 LandPress Content 구조로 변경합니다.

필드 타입

필드 타입은 다음과 같이 매칭했습니다. 대부분 직관적으로 이해할 수 있고, 설명이 필요하다고 판단한 부분에만 설명을 추가했습니다.

Movable Type 필드LandPress Content 필드설명
EditorEditor
Single-Line TextText
  • Movable Type의 Single-Line과 Multi-Line Text는 모두 LandPress Content Text 필드로 매칭했습니다.
  • LandPress Content의 Text 필드는 최대 65,535자까지 입력 가능하며, 공백이나 줄 바꿈 등을 입력할 수 있습니다.
Multi-Line TextText
URLText
Date and TimeDate
Datetime
Time
Drop Down Menu(select)Enum(single)
  • Movable Type의 Select 필드와 Radio 필드는 목록 중에서 하나의 값을 선택할 수 있습니다.
  • LandPress Content의 Enum 필드는 목록 중 하나 혹은 여러 개를 선택할 수 있도록 설정할 수 있으며, 마이그레이션할 때는 하나를 선택할 수 있도록 설정했습니다.
Radio Buttons(radio)Enum(single)
Checkbox(checkbox)Boolean
  • Movable Type의 Checkbox는 '선택함'과 '선택하지 않음'으로 구분합니다. Boolean 동작과 일치하므로 LandPress Content의 Boolean 필드에 매칭했습니다.
Embed ObjectText
Asset(audio, video, image, file)Media(audio, video, image, file)
  • Movable Type의 Asset은 LandPress Content의 Media Library에 매칭했습니다.

연관 관계 데이터

Movable Type의 Category와 Folder는 각각 Article과 Page와 관계있는 데이터입니다. 이 관계를 LandPress Content에서도 유지할 수 있도록 LandPress Content의 Relation 필드를 활용해 연관 관계를 맺어줬습니다.

LandPress Content의 Relation 필드는 컬렉션 간 1:1이나 1:N, N:M 관계를 맺을 수 있도록 지원하는데요. Category와 Article은 N:M, Folder와 Page는 1:N 관계를 맺었습니다. 이렇게 관계를 설정하면 Category와 Folder를 Article과 Page로부터 분리해 쉽게 관리하면서 편리하게 사용할 수 있습니다. 

Relation 구조 설명
Relation 필드 빌더 화면
Article에서 Item 화면
Article Item에서 Category를 선택하는 화면

또한 Category와 Folder는 계층 구조이기 때문에 LandPress Content에서는 자기 자신과 1:N 관계를 맺는 방법으로 계층을 구현했습니다. Category와 Folder의 개별 아이템들은 다음과 같이 하나의 상위 아이템과 여러 개의 하위 아이템을 가질 수 있습니다.

Self Relation 필드 빌더 화면
Category를 저장하는 화면

데이터 추출

데이터 매칭을 완료했으니 이제 Movable Type에서 데이터를 어떻게 추출할지 고민해야 합니다. 두 가지 선택지가 있습니다. XML로 데이터를 추출할 수도 있고, Movable Type의 Data API를 활용할 수도 있습니다.

2022년에 LINE Engineering 사이트를 WordPress에서 LandPress Content로 이관할 때에는 XML로 데이터를 추출해서 이관을 진행했는데요. 아래와 같은 여러 가지 불편함이 있었습니다.

  • 특정 데이터는 XML에 포함되지 않는 경우가 있습니다.
  • 데이터 크기에 따라 XML을 추출하는 게 너무 오래 걸립니다.
  • 일부 사이트만 선택해 마이그레이션하기가 어렵습니다.
  • XML 데이터를 파싱하는 과정이 너무 불편합니다. 

위와 같은 점을 고려해 이번에는 Movable Type의 API를 활용해서 다음과 같은 단계로 데이터를 추출하기로 결정했습니다. 

  1. Movable Type 인증 획득
  2. Site 목록 조회 및 마이그레이션할 Site 선택
  3. Site의 미디어 추출
  4. Movable Type의 데이터 구조 추출
    • Article, Page, Category, Folder의 기본 필드 추출
    • Article, Page의 커스텀 필드 추출
  5. 아이템 추출

데이터 추출 과정에서 발생한 두 가지 문제

그런데 막상 데이터를 추출하려고 하니 버전 문제가 발생했습니다. Movable Type은 버전별로 API 스펙이 다르기 때문에 데이터를 정상적으로 가져오지 못하는 이슈가 있었습니다. 이에 대응하기 위해서는 사용자가 자신의 Movable Type 버전을 선택할 수 있어야 합니다. 또한 인증 문제도 있었습니다. 사용자가 Movable Type 데이터 경로를 커스텀해 사용하는 경우 Movable Type API 경로가 달라지기 때문에 인증 단계에서 실패합니다.

위 두 문제를 해결하기 위해 사용자가 직접 API 엔드포인트를 입력할 수 있도록 변경했습니다.

Movable Type 버전API 버전API 엔드포인트
Movable Type 7 r.53xxv4.0http(s)://path/to/mt-data-api.cgi/v4/
Movable Type 7 r.54xxv5.0http(s)://path/to/mt-data-api.cgi/v5/

마이그레이션 도구 개발

LINE은 글로벌 기업이므로 서비스마다 네트워크 환경이 다른 경우가 있기 때문에 Movable Type에서 LandPress Content로 직접 데이터를 전송하는 것은 불가능했습니다. 이에 사용자가 자신의 PC에서 데이터를 이관할 수 있도록 CLI로 마이그레이션 도구를 개발했습니다.

CLI 개발에 활용한 라이브러리는 다음과 같습니다.

라이브러리활용
Commander.js마이그레이션 도구의 CLI 인터페이스를 제공합니다.
Consola사용자에게 안내 문구를 표시하고, 이관에 필요한 정보를 입력받습니다. 
CLI-Progress대부분 많은 양의 데이터를 이관하기 때문에 마이그레이션 경과를 출력합니다.

마이그레이션 도구를 활용해 사용자가 인증 정보를 입력하고 마이그레이션할 Movable Type Site 목록을 선택하면 다음 과정이 순차적으로 진행됩니다.

  1. Movable Type Site 추출 → LandPress Content Project 생성
  2. Movable Type Asset 추출 → LandPress Content Media Library로 마이그레이션
  3. Movable Type 데이터 구조 추출 → LandPress Content Collection, Field 구조 생성
  4. Movable Type Item 추출 → LandPress Content Item으로 마이그레이션

위 순서에서 주목할 점은 Category나 Folder, Asset을 Article과 Page 아이템보다 먼저 마이그레이션해야 한다는 점입니다. Article과 Page 아이템을 마이그레이션할 때 필드값을 매칭해야 하기 때문입니다.

마이그레이션 실행 화면

헤드리스 CMS로 옮긴 후 개선된 점

여기까지 마이그레이션 도구 개발기를 공유드렸습니다. '기능이 크게 다른 것 같지 않은데 굳이 마이그레이션까지 해야 할까?'라고 생각하실 수도 있을 것 같은데요. 전통적인 CMS에서 LandPress Content로 마이그레이션한 뒤 어떤 점이 개선됐는지 말씀드리겠습니다. 

성능 측면

헤드리스 CMS를 사용한 뒤 미리 빌드해 최적화한 정적 웹 페이지를 제공할 수 있어서 사이트 성능이 향상됐습니다. 또한 LandPress Content는 대용량 트래픽도 처리할 수 있도록 개발한 플랫폼이기 때문에 정적뿐 아니라 동적인 데이터 요청도 문제없이 처리할 수 있습니다. 이에 따라 필요한 부분에서만 API를 활용해 동적인 데이터 요청을 처리할 수 있어서 개발 및 관리가 훨씬 편리해졌습니다. 또한 LandPress Content는 CDN을 통해 전 세계 어디서나 최적의 네트워크 통신을 지원하기 때문에 사이트를 균일하고 안정적으로 운영할 수 있게 됐습니다. 

보안 측면

전통적인 CMS와 달리 프런트엔드와 백엔드 계층이 분리돼 있기 때문에 보안 이슈를 사전에 방지하고 빠르게 대응하는 것이 가능해졌습니다. 무엇보다도 전통적인 CMS는 여러 기능을 보완하기 위해 플러그인을 사용해야 했는데요. 이런 플러그인들에서 보안 이슈가 발생해 데이터를 안전하게 관리하는 데 어려움을 겪곤 했습니다.

하지만 LandPress Content로 전환하면서 이 문제에서 해방됐습니다. LandPress Content는 콘텐츠 관리에 최적화된 다양한 기능을 제공하기 때문에 플러그인을 사용할 필요가 없습니다. 또한 LandPress Content에서 제공하는 CORS(cross origin resource sharing)와 개인 정보 암호화 설정, API 요청 시 특정 필드에 대한 응답을 제외하는 기능 등을 활용해 더 안전하게 데이터를 관리할 수 있습니다. 

개발자 경험 측면

전통적인 CMS는 모놀리식 구조로 유지 보수하기가 어렵지만, 헤드리스 CMS를 사용하면서 프런트엔드와 백엔드가 분리돼 두 계층 간 혼잡으로 발생하는 이슈가 사라졌습니다. 또한 헤드리스 CMS는 프런트엔드 의존성이 없기 때문에 사이트 변경에 유연해서 새로운 기능을 추가하거나 새로운 기술에 대응하는 비용을 줄일 수 있으며, 모든 프런트엔드 프레임워크를 사용할 수 있으므로 프로젝트에 가장 적합한 프레임워크를 선택할 수 있습니다. 이런 장점 덕에 현재 React나 Vue와 같은 현대적인 프런트엔드 프레임워크와 함께 LandPress Content를 사용하는 사이트들이 개발되고 있습니다. 

콘텐츠 관리 측면

기존에는 콘텐츠를 관리할 때 사용하지도 않는 기능 때문에 복잡해진 CMS 관리 화면을 사용해야 했지만, 이제 직관적인 UI와 함께 콘텐츠 관리에만 집중할 수 있습니다. 또한 프로젝트에 따라 가장 최적화된 데이터 구조를 구성할 수 있는데요. 콘텐츠 유형에 따라 컬렉션 타입과 싱글 타입을 선택하고 모듈 단위로 다양한 타입의 필드를 자유롭게 추가할 수 있습니다. 컴포넌트와 필드 그룹을 사용하면 반복되는 데이터 필드 구조를 재사용할 수도 있습니다.

LandPress Content 빌더 화면
LandPress Content 필드 유형

마치며

올해 초 앞서 소개한 마이그레이션 도구를 이용해 데마에칸(出前館, Demaecan) 사이트의 데이터 마이그레이션을 진행했습니다. 미디어 파일을 포함한 3,900여 건의 Movable Type 데이터를 모두 성공적으로 이관했으며 현재는 LandPress Content로 운영되고 있습니다.

지금까지 마이그레이션 도구 개발기와 LandPress Content로 마이그레이션한 후의 변화를 소개했습니다. 앞서 언급한 여러 장점 때문에 LandPress Content를 사용하는 많은 프로젝트가 운영 환경에서도 사용되고 있는데요. 아래는 현재 실제로 서비스하고 있는 웹사이트 화면과 LandPress Content 화면입니다. 각 프로젝트의 특성과 필요에 따라 서로 다르게 구성된 구조를 확인할 수 있습니다.

웹사이트웹사이트 화면CMS 화면
LY Corporation Tech Blog

블로그 목록 화면

Collection type 컬렉션을 사용한 화면

LINE DOSI
메인 화면
Single type 컬렉션을 사용한 화면

이 글이 전통적인 CMS를 사용하며 불편을 겪고 있거나 헤드리스 CMS 사용을 고민하고 계신 분들에게 도움이 되길 바라며 이만 마치겠습니다. 긴 글 읽어주셔서 감사합니다.