컨퍼런스를 진행할 때 Q&A 를 재밌고 쉽게 진행하게 할 수 있도록 직접 웹페이지를 한번 만들어 보았다. 루비로 제작해보고 싶었지만 시간이 촉박해서 평소 사용하던 방법인 servlet, javascript 를 활용하여 페이지를 제작하였다. (자세한 기능은 위의 샘플 페이지를 참고).
jQuery Mobile 라이브러리를 이용하여 사이트 UI 를 구성하였는데, 그동안 Bootstrap 만 사용한 탓도 있지만, jQuery Mobile 의 API 문서가 친절하지 않은 탓에 만드는데 애를 많이 먹었다.
이 글에서는 위 코드를 바탕으로 웹앱을 설계하는 방법에 대해 쓸 것이다. 이 방법이 정답이라고 할 수는 없지만, 지금까지 자바로 웹페이지를 개발을 하면서 가장 효율적인 방법인 것 같다.
시스템 설계
이 사이트를 구성하는 요소는 크게 Tomcat 서버와, Httpd 서버, MySQL 데이터베이스 가 있다. 위의 이미지에서 보듯이 클라이언트에서 사용할 데이터는 80 포트를 통해 받아오고, 클라이언트에서는 javascript 를 통해 톰캣의 포트인 8080 포트로 request 를 보내 정보를 동적으로 받아온다. 톰캣에서 Servlet 을 통해 데이터베이스에 결과를 저장하기도 하고 불러와서 검색 결과를 클라이언트에 전송해주기도한다.
웹브라우저가 Httpd 서버에서 HTML, Javascript 등을 다운받고, 이 코드를 통해서 웹앱 클라이언트의 역할을 하는 것이라고 보면 된다. HTML과 CSS 로 전반적인 UI 를 잡아주고, Javascript는 각 UI 요소들의 동작을 기술하는데, 이는 안드로이드로 따지자면 HTML, Javascript 가 각각 XML, java 소스 코드가 하는 역할과 유사하다고 생각 할 수 있다.
REST API 설계
먼저 클라이언트와 서버간에 정보를 주고 받을 규약(?)을 정해놓아야 나중에 햇갈리지 않는다. REST API 를 설계하여 문서화 시켜놓으면, 효율적으로 웹앱을 만들 수 있고 나중에 보수작업을 할 때도 많은 도움이 된다.
- http://en.wikipedia.org/wiki/Representational_state_transfer (위키피디아 REST 관련 자료)
- http://ko.wikipedia.org/wiki/REST ( 위키피디아 한국어 REST 자료)
- http://developer.naver.com/wiki/pages/Blog (네이버 Open API)
위의 링크들은 REST 와 관련된 자료들이다. 위키피디아에서는 REST를 월드 와이드 웹과 같은 분산 하이퍼미디어 시스템을 위한 소프트웨어 아키텍처의 한 형식이라고 소개하고있다.
Resource | GET | PUT | POST | DELETE |
---|---|---|---|---|
Collection URI, such ashttp://example.com/resources |
List the URIs and perhaps other details of the collection’s members. | Replace the entire collection with another collection. | Create a new entry in the collection. The new entry’s URI is assigned automatically and is usually returned by the operation. | Delete the entire collection. |
Element URI, such ashttp://example.com/resources/item17 |
Retrieve a representation of the addressed member of the collection, expressed in an appropriate Internet media type. | Replace the addressed member of the collection, or if it doesn’t exist, create it. | Not generally used. Treat the addressed member as a collection in its own right andcreate a new entry in it. | Delete the addressed member of the collection. |
위의 표에서는 RESTful API 의 예시를 보여주고 있다. Resource 는 접속 경로에 대한 링크를 적어주고 Method 들에 대한 것을 기술한다.
RESTful API를 대표적으로 볼 수 있는 곳이 여러 API 사이트들이다. 위에 첨부한 링크 중 네이버 Open API 중 Blog 와 관련된 것을 보면 쉽게 이해 할 수 있다. 링크에 들어가서 보면 Resource에 대한 각각의 요청변수와 그에 따른 결과값을 정리해 놓았다. 하지만 네이버 이외에도 다음 API 등 여러 API 들을 살펴보면 각각 다른 형태를 가지고 있다.
RESTful API 를 설계할 때는 기본은 따르되 자신이 보기 편한 형태로 디자인을 하면 될 것 같다.
UI 디자인
어렵진 않지만 웹앱에서 가장 중요한 부분이라고 생각한다. 최근에는 여러 웹 디자인과 관련된 오픈소스들이 많아서 손쉽게 원하는 화면을 구성할 수 있다. 대표적으로 트위터의 Bootstrap, jQuery Mobile 이 있는데, 둘 다 사용해봤지만 모바일용 웹앱을 제작하기 위해서는 jQuery Mobile 이 더 깔끔하게 나오는 것 같다. jQuery Mobile 이 Bootstrap 보다 버벅거리는 것도 적고, 반응성 측면에서도 더 좋다고 생각한다.
전반적인 UI 디자인은 안드로이드, 아이폰 등을 설계할 때와 거의 유사하다. 각 화면 별로 기능을 나누어 스토리보드를 그려보면 개발 할 때 많이 도움이 된다. 위의 예제에서는 “접속화면(index.html)”, “질문하기(qna.html)”, “질문목록(list.html)” 의 세가지 화면으로 간단하게 앱을 구성하였다.
UI의 요소들은 html의 각 node에 attribute를 설정하여 쉽게 적용 할 수 있다. 스토리보드를 구성할 때 이용할 라이브러리의 API 를 참조하면 개발 할 때 금방 UI 제작이 가능하다.
Javascript
HTML 로 UI 를 구성한 후에는 각 UI 요소들에 javascript 를 이용하여 동작을 구현하여야한다. 각 라이브러리에서 제공하는 방식으로 쉽게 버튼 등의 동작을 구현 할 수도 있지만, 제한적인 부분이 있기 때문에 왠만하면 javascript 를 통해 하는 것이 좋다.
위 예제에서는 javascript 를 통해 서버와 통신하고, 각 기능들을 동적으로 만들어주었다. 예를 들자면 버튼을 클릭했을 때 서버에 로그인을 하는 것과 질문을 서버에 등록하는 것, 그리고 서버에서 현재 Q&A 리스트를 받아와 화면에 뿌려주는 기능이 있다. 이러한 기능을 구현할 때 jQuery 를 능숙하게 사용할 줄 알면 간단하게 코딩이 가능하다.
Q&A Platform 과 관련되 자세한 것은 맨 위의 github 링크 에 들어가서 소스를 참고하라.
자주 발생하는 문제 사항 & 팁
javascript 디버깅
C 나 Java 와 다르게 웹페이지는 코드에 에러가 있어도 작동을 하기 때문에 어느 부분에서 오류가 나는지 더 알기가 힘들다. 크롬 브라우저에서는 이러한 오류들을 쉽게 디버깅 할 수 있는 “요소 검사” 라는 기능이 있다. 요소 검사를 이용하면 어디서 오류가 나는지 표시가 되고, HTML의 노드도 쉽게 참고 할 수 도 있다.
요소검사에서 표시해주는 부분은 javascript에 에러가 난 첫 부분이기 때문에, 무작정 javascript를 작성하다보면 오류를 찾는데 엄청난 시간이 들 수도 있다. 따라서 효율적으로 작성하기 위해서는 UI 요소 각각에 따라 순차적으로 코딩을 해나가는 것이다. 버튼이 하나 있다면 먼저 이 버튼을 클릭했을 때 액션과 관계된 코딩을 하나하고 웹페이지에서 테스트를 해본 뒤 다음 코딩을 진행하는 것이 좋다.
예전에 javascript를 처음 했을 때는 html 에서 자바스크립트 부분을 불러오는 위치 때문에 문제를 겪은 적이 있다. javascript 를 head에 선언해 놓는다면 body 가 로딩되기 전에 먼저 자바스크립트를 불러오기 때문에 에러가 발생 할 수도 있다. 따라서 ui 요소와 관계된 것은 body 부분에 스크립트를 삽입하거나, javascript 에서 body 가 로딩 된 이후에 동작하는 함수를 적용해 놓아야 한다. 당연한 이야기지만 무의식중에 간간히 실수할 때도 있으니 조심해야한다.
웹브라우저의 크로스 도메인 설정
javascript 로 ajax post, get 등 통신을 할 때에 보안상의 문제로 브라우저에서 크로스 도메인 접속을 막아 놓았다. 자신의 도메인 일 경우에만 통신이 가능하지만, json api 형태로 제공되는 정보는 callback 메세지와 함께 이용한다면 타 도메인으로의 접속도 가능하다.
이 때문에 웹 서버와 톰캣 서버를 따로 나누어 놓는 것이 좋지 않다. 테스트를 해봤는데 같은 도메인이라도 포트가 다르면 서로 다른 도메인으로 인식되어 통신이 되지 않는다. 위의 예제에서는 이러한 문제를 해결하기 위해 JSON API 형태로 톰캣에서 정보를 제공도록 설계하였다.