'마소'에 해당되는 글 1건

  1. 2008.03.24 [스크랩] 웹코드(WebCode) 구현하기

출처 : http://imaso.co.kr/?doc=bbs/gnuboard.php&bo_table=article&wr_id=32018

2008년도 어느덧 1사분기를 넘어가고 있다. Rapid Web Development를 주제로 필자가 무슨 이야기를 할 수 있을까? 한 꼭지를 맡은 문식이형도 옆에서 원고 작성에 힘겨워 하고 있다. 그러나 실은, 필자의 주제와 소재는 이미 마련되어 있어서 이제 독자에게 어떻게 풀어낼 것인가가 관건이다.

DIY(Doing It Yourself)
웹코드 (WebCode)에 대해서는 간간히 마소의 지면을 통해 흘린(?) 적이 있지만, 그때마다 ‘기회가 되면 자세히 다루겠다’면서 도망 아닌 도망을 다니다 이제서야 기회를 얻게 되었다. 필자는 웹 개발, 즉 동적 웹 사이트 개발을 떠난 지가 상당히 오래되었다. 2006년 여름에 돌아온 웹 개발 계는 확실히 많이 달라져 있었고, HTML 이외에도 CSS와 자바스크립트가 매우 중요해져 있었다. 서버측 로직을 제외하고는 HTML+CSS+자바스크립트(이하 HCJ)의 삼위일체는 웹 개발의 사실상 표준으로 자리 잡았다.

이러한 변화를 보고 필자가 관심을 가진 것은, 일명 ‘뷰’라고 불리는 영역에서만 쓰이는 것으로 생각하는 HCJ만으로도 원하는 기능의 웹 애플리케이션을 만들 수 있지 않을까 하는 가능성이었다.
당 시, ning.com과 같은 DIY 사이트, 즉 사용자가 웹에서 자신의 프로그램을 만들고 돌리는 것이 생겨나고 있었다. 필자는 그 움직임에 주목했지만, 배경에 깔려 있는 서버측 스크립트 기술에 대해 의문을 갖게 되었다. PHP와 같은 서버측 스크립트를 쓰게 되면, 그 실행을 위해 막대한 서버측 컴퓨팅 자원이 필요할 것이고, 샌드박스(sandbox) 모델과 같은 보안을 제공한다고 해도 사용자의 다양한 코드를 안전하게, 특히 다른 사용자에 해를 끼치지 않고 실행할 수 있을까 하는 문제였다.


더 이상 서버의 컴퓨팅 리소스는 필요 없다
그리하여 프로그램 코드와 프로그램이 다루는 데이터는 웹에 있지만 실행은 PC, 즉 클라이언트의 브라우저에서 이루어지는 방식을 생각하기 시작했다. 이것이 웹코드의 1차 개념이다.

이렇게 정리하고 보니, 실제 이런 개념을 실현할 도구가 필요했다. 먼저 코드와 데이터를 둘 곳으로는 스프링노트를 꼽았다. 물론 당시 필자가 스프링노트 팀에 있어서였기도 했지만, 텍스트와 코드의 편집이 매우 원활했다는 점이 그 선택에 크게 작용했다. 소스 코드 단락이 따로 있을 정도로 배려가 있었고, 소스 코드 단락에서의 들여쓰기도 잘 되어 좋았다.

다음은 실행이다. 브라우저에서 코드가 실행되려면, 가장 보편적인 자바스크립트(이하 JS)를 써야 하는데, 안타깝게도 스프링노트는 사용자가 마음대로 JS를 직접 넣을 수도, 실행할 수도 없게 원칙적으로 되어 있었다(간단한 실행이나 테스트는 가능하지만 일반 사용자에게 공개된 기능은 아니다). 그래서 일단 스프링노트에서 소스 코드 단락을 이용해 JS 코드를 넣은 다음, 실행은 스프링노트가 아닌 다른 곳에서 하는 얼개를 만들어 보았다.

JS 코드는 HTML에서 <script> 태그로 표현되어야 브라우저에서 실행한다. 그런데 스프링노트에서 소스 코드 단락은 <ol> 태그로 표현되는 탓에 변환이 필요하다. 그래서 같은 XSLT를 적용하게 된다.

<리스트 1>의 XSLT는 웹코드에서 실제로 쓰이는 것 그대로다. 스프링노트의 본문은 XHTML로 되어 있는데, 이 XSLT를 통과하면 소스 코드 단락이 브라우저에서 실행될 수 있게 바뀐다. 좀 더 구체적으로 실현하면 스프링노트의 본문을 변환하여 웹에 게시(publi shing)하는 무언가가 필요하고, 그래서 만든 것이 스프링북이다.

여기까지 하면 코드를 웹에 두고 실행은 브라우저에서 한다는 개념이 현실화된다. 다만, 코드의 원본이 있는 곳과 코드가 게시되는 곳이 다르다는 매우 독특한 면이 있다.
따라서 사용자는 코드를 실행하기 위해 스프링노트를 부르는 대신, 스프링북을 호출한다. 그럼 여기까지의 이해를 바탕으로 빠르게 간단한 예제를 탐험해 보자.

Hello WebCode
웹코드의 사상을 실천할 수 있는 방법이 스프링노트·스프링북만 있는 것은 아니다. 하지만, 간단하게 쓸 수 있는 레퍼런스로 이 조합을 쓴다고 보면 좋다. 예제를 체험하기 위한 준비물로 웹 브라우저: 파이어버그, HCJ에 대한 기본 지식, 스프링노트 계정, 스프링북 등 좋은 개발 툴이 많은 파이어폭스를 권한다.

스프링북은 http://springbook.playmaru.net에서 서비스형을 신청하여 쓸 수도 있고, 설치형을 직접 깔아 사용할 수도 있다. 여기서는 서비스형을 기준으로 알아본다.
만 약 사용자의 스프링노트가 xyz.springnote.com이라면, 스프링북은 xyz.springbook.playmaru.net으로 생길 것이다. 보다시피 도메인이 다르기 때문에, 코드 작성은 xyz.springnote.com에서 코드 실행은 xyz.springbook.playmaru.net에서 해야 함을 유념하자.

웹코드를 쓰기 위해서는 변환 기능이 필요하다. 스프링노트에서 새 페이지를 만든 다음 앞서 나왔던 XSLT 코드를 내용으로 넣고, transform이라는 태그를 붙인다. 이 과정이 잘 이해되지 않는다면 http://tagstory.com/video/video_post.aspx? media_id=V000145980의 동영상을 참고하길 바란다.

이제 예제용 페이지를 새로 만들고 <리스트 2>처럼 입력한다.

여기에서 주의할 것이 있다. 출처의 URL을 브라우저로 열어보자. 이 코드 부분이 본문과는 다른 단락으로 되어 있다. 즉 소스 코드 단락으로 구분되어 있는데, 그래서 alert(“Hello World”); 줄에서 툴바로 단락 -> 소스 코드를 선택하거나 단축키로 <Ctrl>+<Alt>+<C>를 눌러 코드 부분을 소스 코드 단락으로 둘러싸야 한다.

이렇게 만든 페이지의 URL이 만약 http://xyz.springnote. com/pages/1234567이었다면, 이 예제의 실행은 http://xyz. springbook.playmaru.net/pages/1234567을 브라우저로 열어서 할 수 있다.

코드 편집 (스프링노트) http://xyz.springnote.com/pages/1234567 -> 코드 실행 (스프링북) http://xyz.springbook.playmaru.net/pages/ 1234567

코드의 편집과 실행을 모두 브라우저로 하지만, URL이 구분되어 있다는 점에 유의하자. 만약, 다른 사람(예를 들어 기획자)에게 프로그램의 실행 결과를 보여주고 싶다면 스프링북쪽 URL만 공유하면 될 것이다. 또한 소스 코드만 나누고 싶다면 스프링노트 URL을 가르쳐주면 된다. 아주 간단한 경고 창을 띄우는 정도였지만, 기존 프로그래밍과는 많이 다름을 느낄 수 있다.

1. 로컬 PC의 저장 자원을 쓰지 않는다. 코드가 원격의 스프링노트에 저장된다.
2. 개발 툴을 별도로 설치할 필요가 없이 브라우저 하나면 된다.
3. 웹 환경에서의 실행을 위한 별도의 배포 과정이 들어가지 않는다.
4. 코드 원본과 코드 실행본의 공유가 자유롭다.

필자가 신속한 웹 개발이라는 주제로 웹코드를 소개하는 것도 이런 까닭에서다. 웹 개발자라면 HCJ는 공통필수지만, 서버측 기술은 PHP, 닷넷, 자바 등 다양하고 전문성을 띨 수 있다. 그리고 작게나마 뭔가 하나 만들어서 띄워보려면, 갖추어야 할 것도 많다. 개발 과정의 상당 부분을 선택과 설치에 들이는 것이 작금의 현실이라면, 기존에 잘 알고 있는 기술의 활용을 극대화하면서, 최종 실행만을 웹에서 하는 것이 아니라, 개발의 처음부터 끝까지 웹이라는 플랫폼을 통해 공개와 공유의 정신과 가치를 살려보는 것이다. 절차는 간소화되고, 소통은 편리하게 되어 결국 개발이 물 흐르듯 거침없어지는 웹코드를 경험해보았다.

웹 DB
MVC 모델로 친다면, 지금까지의 논의로 VC, 즉 뷰와 콘트롤러는 다룰 수 있다. 고정된 화면이라면 스프링노트에서 바로 입력해도 되고, 동적이라면 JS의 DOM으로 만들어낼 수 있다. 콘트롤러는 순수한 비즈니스 로직이므로 JS로도 이벤트 주도적인 형태를 구가할 수 있다.

하지만, 하나의 완결된 시나리오를 갖춘 프로그램 치고 M, 즉 데이터 모델을 다루지 않는 것은 찾아보기 힘들다. 필자가 웹코드로 Hello WebCode 다음으로 짠 프로그램이 인기투표 시스템이었는데, 투표 결과를 유지하기 위해 데이터를 어딘가에 저장해야 했다. 물론, 웹코드의 기본 취지에 따라 데이터도 웹에, 그리고 구체적으로는 스프링노트에 있어야한다.

스프링노트는 모든 리소스를 REST 방식으로 제공한다. 그래서 채택한 것이 리소스를 오브젝트로 매핑해주는 ORM(Object-Resource Mapping) 솔루션인 Jester(http://www.jesterjs.org )였다. XHR(XMLHttpRequest)이나 XML 파싱의 부담 없이 편하게 오브젝트 단위로 스프링노트의 리소스를 쓸 수 있게 해준 덕분에, 직접 DB를 다루는 것보다 훨씬 쉽게 데이터를 다룰 수 있게 되었다. 간단한 예제인 <리스트 3>을 한번 살펴보자.

코드만 봐도 매우 직관적임을 알 수 있다. 첫 번째 줄은 Page라는 이름의 리소스 클래스를 만드는 것이다. prefix 매개변수를 쓰는 이유는, 스프링북과 스프링노트가 서로 다른 사이트이므로 스프링북에서 스프링노트의 리소스를 XHR로 바로 접근할 수 없으므로(크로스 도메인 보안) 스프링북에서 프록시를 통해 스프링노트에 접근하기 위해 필요한 것이다. prefix에서 webcode는 접근할 스프링노트 도메인을 가리킨다.

Page.find는 특정 페이지 리소스를 가져올 때 쓴다. 606576은 페이지 ID다. 따라서 이 때 가져올 스프링노트 리소스의 URL은 앞서 prefix 설정과 맞물려 http://webcode.springnote.com/ pages/606576이 된다.
voteResult 오브젝트의 source 필드는 http://webcode. springnote.com/pages/606576.xml에서 source 요소의 내용과 대응된다.

source 요소 안에는 스프링노트 해당 페이지의 내용이 담겨 있다. 그래서 경고창을 통해 내용을 한번 출력하게 된다. 그 아래 코드 부분은 기존의 (<table> 하나가 있는) 페이지 내용을 수정한 다음 voteResult.save()로 저장하고 있다.

이렇게 데이터에 대한 읽고 쓰기 말고도, CRUD(Create, Retrieve, Update, Delete)의 기본 동작을 다 할 수 있다(자세한 것은 Jester 사이트를 참고하길 바란다). 이 정도면 간단한 애플리케이션을 만드는 데에는 부족함이 없어 보인다.

이제는 실전이다 - 설문지
실제로, 필자가 작년에 쓰기 위해 만든 웹 애플리케이션의 대부분을 웹코드로 작성하고 운영했다. 처음에는 아주 간단한 것들이었는데, 사내 투표 시스템을 만들어보고는 좀 더 본격적인 곳에서도 쓰일 수 있겠다는 생각이 들었다.

그러던 중에, 스프링노트 사용성 조사에 쓰이는 설문지가 눈에 띄었다. 이미 PHP로 만든 것으로 1차 조사를 마쳤지만, 2차 조사에 들어가야 하는데 추가 개발할 인적자원이 부족해 난항을 겪고 있었다.
어차피 설문지 초안도 스프링노트에서 작성하는, 아예 개발자 없이 사용성 조사자(비개발자, 이하 UR)가 바로 설문지 애플리케이션을 만들면 어떨까?

그래서 탄생한 것이 SpringBook Q(Questionnaire) Edition(이하 SQE)이다. 아무 정해진 양식 없이  설문지 초안을 만드는 대신, 서로 약속된 형식(구체적으로는 JS 함수)으로 설문지를 스프링노트에 만들면, 스프링북에서 바로 실행되는 것이다. 물론 UR은 JS를 배운 적도 없지만, 그야말로 SQE에 필요한 정도만 가르쳐줬다. <리스트 5>는 간단한 설문지 페이지다.

JS 인터페이스를 최대한 비개발자도 이해하기 쉽도록 설계하려 노력했다. SQE에 대한 자세한 사항은 공식 사이트 http:// sbq.springbook.playmaru.net/을 참고하길 바란다. 여기에서는 SQE를 만들면서 맞닥뜨렸던 문제와 해결에 대해 독자들과 함께 나누려고 한다.

사용자 인증
중복 답안을 막기 위한 설문지의 특성이기도 하지만, 웬만한 사이트를 만들면서 사용자 인증 기능이 없는 경우는 흔치 않다. 하지만 사용자 인증을 서버측 로직 없이는 할 수 없어서, Open ID 인증 기능을 스프링북에 넣게 되었다. 이것 또한 /session 리소스에 CRUD를 하는 것으로 대응되는데, 웹코드로 편하게 로그인·로그아웃 기능을 넣기 위해 <리스트 6>과 같은 라이브러리를 만들어 보았다.

<리스트 6>을 이용하여 간단하게 인증 창을 표시하는 페이지는 <리스트 7>과 같다.

출처를 직접 브라우저로 열어보면 알겠지만 #742768@ webcode# 부분은 일반 본문이고, window.onload=auth;는 소스 코드 단락이다. #...# 구문은 다른 페이지에 있는 라이브러리를 포함하는 명령이다. 즉 굳이 복사해서 붙여올 필요 없이 해당 라이브러리 페이지의 ID와 도메인만 알면(그리고 읽기 권한이 있으면) 위와 같이 그 라이브러리를 불러 올 수 있다. 또 하나, 인증 영역을 그리기 위해 미리 auth라는 id의 div가 마련되어 있어야 한다. 이 라이브러리를 통해 로그인을 하게 되면, 쿠키에 openid라는 키로 사용자의 OpenID URL이 들어가게 된다. 그래서 이후 클라이언트의 JS 코드에서도 사용자의 로그인 여부, OpenID 등을 파악할 수 있게 된다.

페이지 전환
사용자 인증 다음으로 당면한 문제는 화면 전환이었다. 페이지 간 이동은 무겁기도 하고, 상태 데이터를 넘겨주고 받기도 불편했다. 그래서 고안한 것이 미리 표시할 화면들을 준비해둔 다음, 주어진 상황에서 보여줘야 하는 화면만 표시하고 나머지는 가려두는 방식을 취했다. 같은 MVC 구조라고 해도, 페이지 간 이동이 아닌 화면 간 이동이라는 점에서 콘트롤러를 JS로 짰을 때는 다른 양상을 보여주는 셈이다.

<리스트 8>은 SQE 라이브러리에서 화면 전환 처리를 맡는 함수다. Prototype을 써서 편리하게 보여주고 숨기는 일을 한다.

크로스 브라우저 지원
이 문제가 최종 사용자에게 있어 가장 중대한 것이었다. 파이어폭스로는 잘 되던 것도 인터넷 익스플로러(이하 IE)에서는 잘 안 되는 것들이 생겨나기 시작했다. 결국 깔끔하던 코드에 이런저런 핵(hack)이 끼어 들어가고, 분기에 분기를 거듭해서 겨우겨우 모든 기능이 두 브라우저에서 모두 잘 돌아가게 만들었다.

이 문제의 해결에 거의 전체 개발의 4분의 1의 노력이 들어갔다. 만약 만들고 쓸 애플리케이션의 사용자 브라우저를 파이어폭스로 고정할 수 있다면 이런 공수는 절약할 수 있을 것이다. 특히 팀 내부의 빠른 프로토타입 만들기라면 특정 브라우저에 한정 짓는 것은 현명한 선택이라 생각한다.

하지만, 다양한 브라우저 지원을 외면만 할 수는 없다. 한국에서는 IE가 대다수라지만, 해외에서의 파이어폭스와 오페라, 그리고 사파리의 두드러진 약진을 예의주시하는 정도가 아니라 따라가 줘야한다. Prototype이 다소 도움을 주고 있지만, 웹코드를 실제 서비스용으로 점차 쓰게 되면서 크로스 브라우저 지원을 위한 중간계 라이브러리도 성장하기를 바란다.

From fast prototyping to production service
웹 코드의 개념이 탄생한지는 1년이 넘었지만, 실제 손에 잡히는 플랫폼이 나온 지는 반년도 되지 않은, 그야말로 걸음마 단계인 상황이다. 이번 WoC 2007에 유현규 님과 함께 SQE를 한층 발전시키는 작업을 하면서, 여러 가지로 갈 길이 멀다는 것을 깨달았다. 그렇지만 서두르지 않고 차근차근 나아가며 가볍고 손쉬운 개발·실행 플랫폼으로 진화하려고 한다.

웹코드는 만능이 아니다. 되레 무척 제한적이기까지 하다. JS의 부족함을 그대로 물려받은 태생적인 한계도 있다. 그러나 프로그램의 기본이 사용자의 데이터 처리라는 사실을 상기하면, 웹코드로 할 수 있는 것은 무한하며 자유롭다. 투표나 설문지에 이어 블로그나 게시판과 같은 더 본격적인 예제로 웹코드를 다룰 수 있는 기회를 가지기를 희망한다.

신고
Posted by 타임워커™
TAG


티스토리 툴바