2008년 8월 16일 토요일

HTTP 모델링하기

텍스트큐브닷컴에 글을 쓰는 건 꽤 오랜만인 것 같다;; 그 사이 업데이트도 좀 된 것 같고... 글을 쓰긴 써야 할 것 같아서 요즘 한창 생각하고 있는 주제 중 하나를 써본다. (그래도 '웹'에 관한 블로그라고 했으니 그쪽 관련된 것으로 골랐다-_-)

요즘 스팍스에서 KSearch (가제)라는 카이스트 내부를 대상으로 하는 검색 엔진 프로젝트가 진행 중인데, Lucene과 Python을 기반으로 만들면서 후배 녀석들이 웹브라우저와 통신하는 프론트엔드 서버를 위해 말 그대로 SimpleFramework를 만들어둔 것이 있다. 그쪽을 맡아서 하던 후배가 교환학생(...)을 가버리는 바람에, 또 마침 내가 좀 시간이 생겼기도 하고 해서 내가 그 부분을 맡아서 계속 작업해나가는 중이다. (내가 한 작업으로는 Django의 템플릿 엔진을 떼어와 얹은 것 등이 있다)

앞으로 프론트엔드 전체를 Django로 갈아엎어버릴지까진 모르겠지만 Django의 경우 DB와 반드시 연동되어 돌아가야 하고 그와 관련하여 설정을 별도로 해줘야 하는 등 순수 검색 인터페이스만을 위한 단순 UI 구성에는 귀찮은 면이 있어 초간단 WSGI 인터페이스 wrapper를 만들어 쓰고 있다.

Python에서 사용하는 웹서버 CGI 규격이라고 할 수 있는 WSGI 인터페이스가 어느 정도 기본적인 처리는 해주지만 이것을 좀더 쓰기 편하게 만들려면 역시 HTTP에 대한 이해가 필요하다. 여기서는 HTTP를 다루는 프레임웍을 만들고자 할 때 어떤 점들을 고려하면 좋을지 간단히 써보려고 한다.

Request - Response

웹이라는 건 기본적으로 웹브라우저(client)와 웹서버(server) 사이의 통신에 의해 구현된다. 그 통신 방법은 보통 HTTP라는 프로토콜을 이용한다.

웹브라우저는 웹서버에게 이러이러한 정보를 달라고 요구하거나 웹서버가 어떠어떠한 동작을 해줬으면 하는 request를 보내고, 웹서버는 이를 처리한 후 결과를 response한다. Request의 종류는 몇 가지가 더 있지만 나머지는 잘 쓰이지 않고 보통 GET/POST 두 가지를 사용하며 GET은 어떤 정보 제공을 요청하는 것이고 POST는 웹브라우저가 데이터를 제공하고 그에 대한 처리 결과를 알려달라고 요청하는 것이다.

HTTP의 경우, 일반적으로 한 번의 request-response 쌍이 오가고 나면 연결이 끊어진다. 따라서 로그인과 같은 기능을 구현하려면 여러 client들로부터 날아오는 request들을 각 client 단위로 구분하고 인증할 방법이 필요한데, 이것이 세션과 쿠키이다.

쿠키는 웹서버가 웹브라우저에 뭔가 작은 크기의 정보를 저장할 수 있게 해주는데, request가 들어올 때마다 쿠키를 조회하여 자기가 기록했던 정보를 알 수 있다. 따라서 로그인 인증 과정에서 부여한 (랜덤한) 고유값을 쿠키에 넣어두고 그 고유값과 인증 여부의 mapping을 웹서버가 가지고 있으면 그 client를 로그인 상태로 유지하고 쇼핑몰 장바구니와 같이 계속 가지고 있어야 하는 정보들을 관리할 수 있다.

따라서 모델링에는 Request로 날아온 데이터를 잘 unpack해서 다루기 쉽게 해주는 부분과, session을 관리하고 현재 session이 가지고 있는 데이터를 다룰 수 있게 해주는 부분, response와 그 출력을 작성할 수 있게 해주는 부분들이 포함되어야 한다.

Response의 세분화

그러한 웹서버의 response에는 여러가지 종류가 있는데, HTTP specification을 보면 잘 처리되었음을 알리는 200번대 응답코드와 다른 페이지로 이동하라는 것을 알리는 300번대 응답코드, 요청을 수행할 수 없음을 알리는 400번대/500번대 응답코드가 있다.

가장 많이 사용되는 것은 200 OK, 302 Found, 403 Forbidden, 404 Not Found, 500 Internal Error 정도가 되겠다. 그외 세부적인 코드들도 많이 있지만 보통 이 정도만 알고 있으면 무방하다. OOP 언어를 사용한다면 클래스 상속 정도로 모델링해볼 수 있겠다.

Ajax 처리하기

뭔가 특별하고 새로운 신기술 같아 보일 수도 있는(...) Ajax도 기본적으로 request-response라는 건 똑같은데, 다만 그것이 웹브라우저에서 봤을 때 페이지 이동 없이 javascript를 이용해 문서의 일부분만 갱신하는 형태로 보여진다는 것이 다를 뿐이다. 웹서버 입장에서는 다른 것이 전혀 없다.

디버깅 요소 집어넣기

웹프로그래밍에서 가장 어려운 것은 디버깅이다. 간단한 문제라면 웹출력에 몇 가지 문자열을 더 찍어보는 것으로 해결되겠지만 복잡한 것들은 이런 방식으로는 찾아내기 힘들고, 프레임웍 구조나 사용 환경의 차이에 따라 response 출력 과정에서 중간에 '끼어들어' 문자를 찍는 것 자체가 불가능하거나 매우 까다로울 수도 있다.

Django 디버그 모드 오류 페이지 (ⓒDorkyCute)

위 그림은 Django 프레임웍의 디버그 화면이다. 500 Internal Error를 날리되 거기에 디버깅 정보를 함께 실어준다. 코드가 진행되다가 처리되지 않은 예외가 발생할 경우 이렇게 stack trace와 각 단계에서의 local variable 정보, 에러 메시지와 그 위치 등을 상세하게 표현해주는데, 프레임웍을 설계한다면 디버깅 기능은 반드시 고려해야 할 중요한 요소다.

잡다한 표준들

캐시 제어 및 시간 표현을 위한 RFC 규약들, Form 데이터를 주고받기 위한 인코딩/디코딩 방법, 올바른 MIME-Type 지정하기 정도가 기본적으로 고려되어야 할 부분들이다. 여기에 Django처럼 보다 추상화된 형태의 Form 등을 지원한다면 더 좋을 것이다.

-

뭐 대충 적어봤다. 아는 사람한텐 다 아는 내용일 테지만 나 스스로도 요구사항을 정리하는 관점에서 간단하게 적어보았다. 여기에 부가 기능을 더한다면 표현과 로직을 분리하기 위한 template 엔진이나, DB를 쉽게 다루기 위한 ORM 등이 있을 수 있겠다.

댓글 없음:

댓글 쓰기