2014년 12월 11일 목요일

BynamoDB: High Level DynamoDB Interface for Python

AWS에서는 DynamoDB라는 NoSQL 데이터베이스 서비스를 제공한다. 파이썬 프로젝트라면 AWS에서 제공하는 boto를 이용해 DynamoDB를 관리할 수 있다. boto의 DynamoDB 인터페이스는 DynamoDBConnection 부분과 그 외의 부분으로 나눌 수 있다. DynamoDBConnection은 저수준 인터페이스로 DynamoDB 명세를 충실하게 구현해 두었고, 나머지는 이를 쉽게 이용할 수 있게 만든 고수준 인터페이스다.
프로젝트에서 DynamoDB를 이용하기로 결정해서 boto를 사용하기로 했다. 하지만 boto를 이용해 관리해보니 몇가지 불편한 점이 있었다. 가장 크게 불편했던 것은 테이블의 schema를 정의할 수 없다는 것이었다. 테이블의 schema를 정의할 수 없다보니 속성 이름과 아이템 속성에 어떤 타입이 들어가야 하는지 헷갈리는 경우도 있었고, 고수준 인터페이스를 이용해 가져온 아이템의 속성값은 문자열 키를 이용해 접근해야만 했다. 다른 불편함은 Complex Lookup을 포함한 몇 몇 기능들이 고수준 인터페이스에서 숨겨져 있다는 것과 실제 사용하기에도 불편하다는 것이었다.
어딘가에는 이런 불편함을 해결해준 패키지가 있을 것 같아서 다른 DynamoDB 파이썬 인터페이스를 찾아보다가 PynamoDB를 발견하게 되었다. 개발 중 가장 크게 불편하게 느꼈던 schema부분을 해결해줄 수 있었다. 상당히 잘 짜여진 인터페이스처럼 느껴져서 사용해볼까 하다가 말았다. boto와는 동떨어진 독립적인 프로젝트 이면서도 DynamoDB의 모든 기능을 제공하지 않아 제공하지 않는 기능을 사용하려면 boto를 사용해야 했기 때문이다. Complex Lookup이 그 중 하나인데 이 기능을 사용할 수 있는 방법이 PynamoDB에 아예 없었다. 또 boto에서 제공하지 않는 기능은 똑같히 제공하지 않고 있어 고쳐 사용하려면 boto, PynamoDB 둘 다 고쳐야 했기 때문이다. boto에서 List와 몇가지 타입을 제공하지 않고 있었는데, PynamoDB도 똑같히 제공하지 않고있었다. (관련 boto issue). 한마디로 DynamoDB를 사용하는데 두개의 독립된 패키지에 의존하게 되는게 불편했다.
그래서 PynamoDB를 패치할까, boto에 기능을 추가하고 더 쉽게 사용할 수 있는 인터페이스를 만들어 사용할까 하다가 후자를 선택했다. 그리고 나와 같은 불편함을 느끼는 사람이 있을 것 같아서 파이썬 패키지로 GitHub에 공개해두었다. BynamoDB에서 확인할 수 있다. 이름의 의미는 그냥 boto에 의존성을 가지고 있어서 B로 시작하게 했다. BynamoDB의 특징은 각 프로젝트에서 사용하고 있는 boto에 의존해 사용할 수 있다는 것이다. 사용하고 있는 boto에서 List 타입 패치를 적용하면 BynamoDB에 ListAttribute만 추가해 사용하면 된다. 또 하나는 모든 API가 boto의 DynamoDBConnection을 이용한다는 것이다.
내 책임 하에 있는 패키지를 처음 작성해 본 것이라 어설픈 점이 많이 보일 수 있다. 그리고 우리 프로젝트에 사용하는 것을 우선해 우리 프로젝트에서 사용하지 않는, 혹은 중요도가 떨어지는 기능은 아직 구현하지 않았다. 예를 들면 batch get API라던가 filter expression에서의 몇 몇 연산자들이 있다. 사용하고 싶은데 어색한 부분이나 추가하고 싶은 기능이 있으면 알려주시거나 패치해서 풀리퀘 부탁드립니다 :)

2014년 9월 3일 수요일

코드의 중복제거보다 코드의 기능구분이 우선되야한다.

비교적 최근에 Clean Code를 읽었다. 이 책은 깨끗한 코드를 작성하기 위한 많은 원칙들을 제시하고 있는데, 이 중에 하나가 소프트웨어에서 모든 악의 근원은 코드 중복이라고 말하며 설명하는 DRY원칙(Don’t Repeat Yourself)이다. 코드에서 중복이 존재한다면 이는 한가지 기능단위로 구분할 수 있으니 함수로 추출해서 가독성도 높히고 관리도 쉽게 하라는 요지다. 하지만 저번 주의 경험을 통해 코드 중복을 제거할 시 중복되는 코드를 정말 한 개의 기능단위로 정의하고 함수로 추출할 수 있는지에 대한 판단이 동반되어야 한다고 생각하게되었다.
스터디서치 모바일 웹을 만들 때 이야기다. 모바일웹이라도 같은 서비스이다보니 기존의 데스크탑 웹과 동일한 자원과 유저 플로우를 이용하게 된다. 따라서 우리는 모바일 웹을 개발할 때 빠르게 개발하기 위해서 모바일 웹이 데스크탑웹과 같은 Django View, View 함수를 사용하게하고, 모바일 웹의 HTML페이지 요청은 html경로에 mobile/만 추가되도록 하였다. 이를 통해 우리는 서버단에서 중복되는 코드 없이 모바일웹을 작성할 수 있었다.
하지만 저번 주에 한가지 문제가 발생했다. 데스크탑 웹을 리뉴얼하면서 회원가입 페이지를 모달로 띄워주기로 결정하였고, 따라서 데스크탑 웹에서는 회원가입 페이지를 보여주기 위한 View 함수가 필요 없어지게 되었다. 순간 모바일웹의 존재를 잊어버린 나는 그 View 함수를 지워버렸고, 그 상태에서 릴리즈하여 내가 12시간 뒤 ‘아차’ 할 때까지 같은 View 함수를 사용하던 모바일웹에선 회원가입페이지를 볼 수 없었다.
실제로 모바일 웹을 제공함에 있어 데스크탑 웹에서 사용하던 View를 거의 그대로 이용해도 될만큼 동일한 기능들이 대부분이다. 따라서 회원가입 페이지를 보여주는 함수의 기능단위를 “회원가입에 필요한 페이지를 보여주는 함수"라고 정의해도 큰 문제가 없을 수 있다. 하지만 좀 더 좋은 디자인은 "모바일웹에서 회원가입 페이지를 보여주는” 함수와 “데스크탑웹에서 회원가입 페이지를 보여주는” 함수를 분리하고, 그 함수들의 같은, 혹은 중복된 부분의 코드를 함수로 추출해 두 개의 함수에서 호출하는 디자인일 것이다. 이와 같이 기능단위를 어떻게 구분할 지 결정하는 것은 많은 노련미가 필요할 것 같고, 아마 Clean Code 저자분들은 너무 당연한 이야기라 적어두지 않았나 싶다.

2014년 8월 23일 토요일

블로그를 시작하려합니다.

어렸을 적부터 남들에게 나를 드러내는 일을 싫어하곤 했습니다. 내 경험과 생각을 남들에게 공유하기엔 아직 깊이가 부족한 사람이라는 부끄러움과 가만히 있어 중간이라도 가자는 생각때문이였던 것 같습니다. 하지만 이러한 태도가 저의 성장에 장애물이 된다는 것을 요즘들어 많이 느껴서 고치려고 합니다.
이를 위한 첫번 째 노력으로 블로그 포스팅을 시작합니다. 블로그에 쓴 글이 얕고 틀린 생각이라 나중에 혼자 이불킥 할지라도 매 일, 매 주 경험하고 느낀 것을 기록해두고, 내 생각을 전달하기 위해 차분히 글을 작성하고, 남들에게 보여준 후 피드백을 받고 그 과정에서 한 번 더 생각해 보는 경험이 저에게 많은 가치를 줄 것이라 생각하기 때문입니다. 더 나아가 누군가에게 저의 글이 도움이 되었으면 하는 바람, 또 그런 글을 쓸 수 있는 사람이 되기 위함도 있습니다.
포스팅의 내용은 주로 회사에서의 생활과 개발 과정에서 배운 점과 느낀 점이 될 것입니다. 아낌없는 조언 부탁드립니다 !