라이브러리까지 골랐으면 이제 진짜 중요한 결정 하나가 남아요. 사용자가 쓴 글을 어떤 형태로 저장하느냐예요. 저는 예전에 이걸 대충 정했다가 1년 뒤에 크게 후회했어요. 저장 형태를 바꾸려면 이미 쌓인 글 전부를 손봐야 하거든요. 큰 축은 둘이에요. HTML을 통째로 저장하느냐, 아니면 구조화된 문서 모델(JSON 같은 데이터)로 저장하느냐죠. 오늘은 이 둘의 장단점을 비교하고, 언제 무엇을 골라야 하는지 정리할게요. 오래 갈 서비스일수록 여기서 갈려요.

18.1 저장 형태가 왜 그렇게 중요한가요?

글 하나를 저장한다는 건 미래의 나와 약속하는 일이에요. 그 글은 나중에 다시 편집도 되고, 목록에 미리보기로 나오고, 검색에도 걸리고, 앱이 생기면 다른 화면에도 뿌려져야 해요. 이 모든 쓰임을 저장된 형태가 좌우해요.


그래서 저장 형태는 한 번 정하면 바꾸기 힘든 뼈대예요. 대충 정하면 나중에 수만 개의 글을 새 형태로 옮기는 대공사가 기다려요. 그러니 처음에 두 방식의 성격을 제대로 알고 고르는 게 중요해요.


제 실패담을 하나 보태면, 초기에 HTML만 저장해 뒀다가 나중에 앱을 만들 때 크게 당했어요. 앱 화면은 웹 HTML을 그대로 못 쓰는데, 저장된 게 HTML뿐이라 글마다 억지로 변환하느라 고생했죠. 그때 데이터로 저장했더라면 하고 얼마나 후회했는지 몰라요. 저장 형태 하나가 몇 년 뒤의 나를 웃게도, 울게도 해요.

18.2 그냥 HTML로 저장하면 안 되나요?

가장 쉬운 길은 편집창의 HTML을 그대로 저장하는 거예요. contenteditable 안에 이미 HTML이 들어 있으니, 그걸 통째로 데이터베이스에 넣으면 끝이에요.


<p>안녕하세요 <b>반갑습니다</b></p>


장점이 분명해요. 보여줄 때 그대로 화면에 꽂으면 되니 편해요. 따로 변환할 필요가 없죠. 급하게 만드는 게시판이라면 이게 제일 빨라요. 하지만 함정이 있어요. HTML은 같은 모양을 만드는 방법이 여러 가지예요. 굵게를 b로도, strong으로도, style이 붙은 span으로도 표현할 수 있죠. 그래서 모양은 같은데 코드는 제각각인 글이 쌓여요. 나중에 일괄로 다루기가 지옥이에요.


또 하나 걸리는 게 다시 편집할 때예요. 저장한 HTML을 편집창에 도로 넣으면, 브라우저가 그걸 또 자기 식으로 손봐서 코드가 조금씩 달라져요. 저장하고 불러오길 반복할수록 미세한 변형이 쌓이는 거죠. 급한 게시판이면 넘어가도, 오래 두고 편집될 글이라면 이 점이 은근히 성가셔요.

18.3 HTML 저장은 뭐가 위험해요?

더 큰 문제는 보안이에요. 사용자가 넣은 HTML을 그대로 화면에 꽂으면, 그 안에 숨은 나쁜 코드가 실행될 수 있어요. 남의 글에 몰래 심은 script 태그 하나로 다른 사용자의 정보가 털릴 수 있거든요. 이걸 XSS(교차 사이트 스크립팅, 남의 화면에 악성 코드 심기)라고 해요.


그래서 HTML을 저장하고 보여줄 땐 반드시 청소(sanitize, 위험한 태그 걸러내기)를 거쳐야 해요. 믿을 만한 청소 도구로 허락한 태그만 남기고 script나 위험한 속성은 제거하는 거죠. 이 청소를 한 번이라도 빼먹으면 사고로 이어져요. HTML 저장이 편해 보여도, 이 안전장치는 절대 생략 불가라는 걸 꼭 기억하세요.

18.4 구조화된 문서 모델은 뭐가 달라요?

다른 길은 글을 HTML이 아니라 데이터로 저장하는 거예요. 요즘 라이브러리들은 문서를 JSON 같은 구조화된 형태로 다뤄요. 앞서 나온 Quill은 이걸 델타(Delta)라고 부르죠. 같은 글이 델타로는 이렇게 생겼어요.


{ "ops": [
{ "insert": "안녕하세요 " },
{ "insert": "반갑습니다", "attributes": { "bold": true } }
] }


보면 무슨 글자에 어떤 서식이 붙는지가 데이터로 또렷하게 적혀 있어요. HTML처럼 표현이 애매하지 않고, 굵게는 언제나 bold: true 딱 하나예요. ProseMirror나 Slate도 형태만 다를 뿐 문서를 데이터 나무(tree)로 다룬다는 점은 같아요. 저장할 땐 이 데이터를 넣고, 보여줄 땐 이걸 HTML로 바꿔 뿌려요.


여기서 오해하기 쉬운 게 하나 있어요. 데이터로 저장한다고 HTML이 사라지는 건 아니에요. 화면에 보여줄 땐 결국 이 데이터를 HTML로 바꿔서 그리거든요. 다만 그 변환을 에디터가 정한 규칙대로 하니, 아무 HTML이나 들어오는 게 아니라 내가 아는 모양만 나온다는 게 핵심이에요.

18.5 데이터로 저장하면 뭐가 좋아요?

가장 큰 이점은 다루기가 명확하다는 거예요. 표현이 하나로 정해지니 검증하기 쉽고, 규칙에 안 맞는 글은 애초에 못 들어와요. 또 이 데이터를 여러 형태로 변환할 수 있어요. 웹에는 HTML로, 앱에는 앱에 맞게, 검색용으로는 순수 텍스트만 뽑아내기도 쉬워요.


보안 면도 유리해요. 내가 아는 서식만 데이터에 담기니, 화면에 그릴 때 정해진 태그만 만들어져 위험한 코드가 낄 틈이 적어요. 게다가 여러 명이 동시에 편집하는 협업 기능도 이 데이터 방식이라야 제대로 만들 수 있어요. 누가 어디를 바꿨는지 조각(op) 단위로 주고받아야 하거든요. 대신 보여줄 때마다 변환이 필요하고, 초반에 손이 더 많이 가요. 공짜 장점은 없죠.


실제로 겪어보면 서식 규칙을 바꿀 때도 차이가 나요. 나중에 굵게의 표현을 손보거나 새 서식을 넣어야 할 때, 데이터로 저장돼 있으면 규칙만 고쳐 다시 그리면 돼요. HTML로 굳어 있으면 글 하나하나를 뜯어고쳐야 하죠. 서비스가 오래갈수록 이 차이가 크게 벌어져요.

18.6 그래서 실무에선 뭘 골라요?

기준은 글의 수명과 쓰임새예요. 서식이 단순하고 한 화면에서만 쓰는 급한 게시판이면 HTML 저장도 괜찮아요. 대신 청소는 필수고요. 반대로 오래 갈 서비스, 앱과 웹에 함께 뿌리거나 검색, 협업이 필요하면 구조화된 데이터가 정답이에요.


현실에서 자주 쓰는 절충도 하나 있어요. 데이터(JSON)를 원본으로 저장해 두고, 보여줄 HTML은 미리 만들어 함께 저장하는 방식이에요. 편집할 땐 원본 데이터를 쓰고, 보여줄 땐 미리 만든 HTML을 바로 꽂아 빠르죠. 원본이 데이터라 나중에 형태를 바꾸거나 다른 화면에 뿌리기도 자유롭고요. 저장 공간은 조금 더 쓰지만, 속도와 유연함을 둘 다 챙기는 실속 있는 선택이에요. 물론 원본과 HTML이 서로 어긋나지 않게 항상 같이 갱신하는 것만 지키면 돼요.

18.7 오늘 정리

오늘은 에디터 데이터 모델, 즉 글을 어떤 형태로 저장할지를 다뤘어요. 저장 형태는 한 번 정하면 바꾸기 힘든 뼈대라 처음이 중요했죠. HTML 저장은 그대로 화면에 꽂아 편하지만, 표현이 제각각이라 다루기 어렵고 XSS 위험 때문에 청소가 필수였어요. 구조화된 데이터(델타나 JSON)는 표현이 또렷해 검증, 변환, 협업에 강하지만, 보여줄 때 변환이 필요하고 초반 품이 더 들었고요. 고를 땐 글의 수명과 쓰임새로 판단하되, 데이터를 원본으로 두고 HTML을 함께 저장하는 절충이 실무에서 실속 있었어요. 여기까지가 에디터 이야기예요. 저장 형태 하나가 편집, 미리보기, 검색, 협업, 앱 확장까지 전부 좌우한다는 걸 기억해 두세요. 화면에 편집기 하나 얹는 일이 왜 그렇게 깊은지, 이제 감이 잡히셨길 바라요.