렛츠 끼릿의 메인 페이지에서는 공연정보와 더불어서 당일에 가장 인기 있는 부스(주점, 플리마켓 등등)를 나타내주고 있습니다.
위의 사진과 같이 인기 있는 부스를 5개만 추출하여 나타내주고 있었습니다. 이 때 인기있는 부스의 기준으로는 여러가지가 의논이 되었습니다.
댓글이 많은 것
을 인기있는 부스라고 하자조회수가 많은 것
을 인기있는 부스라고 하자좋아요가 많은 것
을 인기있는 부스라고 하자이 3가지 중에서 좋아요가 많은 것
을 인기있는 부스로 하자는 결정이 나왔습니다. 그 이유는 댓글같은 경우 사용자들이 접근하는 장벽이 높다는 의견이 많았었고 조회수 같은 경우에는 새로고침으로 무한하게 늘릴 수 있다는 의견이 있어서 였습니다. 그래서 한 사람당 한번만 할 수 있는 좋아요
를 인기있는 부스의 척도로 삼았습니다.
좋아요
라는 것은 특정 사용자가 식별이 되어야 하는데 이번에 많은 학교 학우들이 편리하게 서비스를 이용할 수 있도록 로그인이라는 장벽을 두지 않았습니다. 그래서 좋아요를 누른다고 한들 사용자가 정보가 없는 상태에서 이를 사이트를 나갔다가 들어왔을 때 어떻게 인식을 해주어야 할지 고민이 되었고 여러 방면으로 이를 해결할 수 있는 방안에 대해 모색을 했습니다.
좋아요를 누른 사용자를 식별하는 방법으로 크게 2가지 의견이 나왔습니다.
이 두 방식 중 ip 주소로 사용자를 식별하는 것에는 큰 결함이 있다고 판단했습니다.
이는 위의 그림과 같이 교내에서 여러 학우들이 같은 wifi를 이용하는 경우 내부적으로 각 기기는 다른 ip 주소(사설 ip 주소)를 가지지만 외부 서비스에 입장에서 ip는 같게 나타난다는 것입니다. 그래서 여러 사용자가 같은 ip 주소로 처리가 되어 ip주소로는 사용자를 식별하는 것이 불가능한 상황이 됩니다. 또한 유동 ip로 인해서 사용자의 단말기 ip 주소가 변경이 된다면 기존에 좋아요를 눌렀던 정보도 파악할 수 없는 상황도 존재했습니다.
이와 같은 이유로 사용자를 식별하는데 ip주소를 이용하지 않았습니다. 그래서 남은 방법인 쿠키를 이용하는 방식으로 문제를 해결했습니다.
위의 그림과 같이 사용자가 어느 한 부스에 좋아요를 누르면 서버는 쿠키를 발급을 해줍니다. 쿠키는 겹치지 않는 정보를 가지게 했고 쿠키를 통해서 좋아요를 식별하는 방식을 선택했습니다.
이후 요청에는 쿠키가 함께 보내지게 되고 서버는 쿠키 정보를 통해서 사용자가 좋아요를 눌렀는지 아닌지 여부를 반환해줍니다. 즉, 사용자를 식별하는 방식이 아닌 쿠키로 좋아요를 식별하는 방식을 채택했습니다.
쿠키는 서버의 데이터 조각이며 개발자 도구를 통해서 사용자들이 확인을 할 수 있습니다. 즉, 사용자에게 쉽게 노출되어 있는 구조입니다. 그렇기에 중요한 정보를 담으면 안되고 각 쿠키의 값이 식별되는 것이 핵심이었습니다. 그래서 저희팀은 Java에서 제공하는 UUID를 이용해서 쿠키의 value를 설정했습니다.
좋아요 객체에 경우 크게 세가지의 컬럼을 가지도록 하였습니다. Pk인 id와 쿠키의 value가 될 cookieKey 그리고 어떤 부스에 좋아요인지를 파악하기 위해 Booth 객체와 관계를 가지도록 구성을 했습니다.
다음은 서비스 Layer에 대해서 살펴보겠습니다.
create메소드에서는 부스 id와 해당 요청자의 쿠키의 key, value를 포함한 정보를 인자로 받습니다. 이를 통해 해당 사용자가 이미 해당 부스에 좋아요를 했는지 검증한 후 Like의 Key를 생성하고 이를 DB에 저장합니다. Like의 Key 값은 서비스 내에서 유일해야하기 때문에 고유성을 보장하는데 이용하는 UUID를 활용했습니다.
현재 UUID를 생성하는 객체는 한번 추상화를 하여 인터페이스를 구현하도록 구성을 했는데요! 그 이유는 테스트의 편의성을 높이기 위함이었습니다. 일련의 문자열을 UUID의 randomUUID() 메소드를 통해 반환되는데 이를 예측해서 테스트를 하는 것을 불가능에 가까웠습니다. 그래서 테스트에서는 일정한 값을 반환하는 UniqueKeyMaker의 구현체를 만들고 진행하였습니다.
마지막으로 controller에 대해서 살펴보겠습니다.
web 계층에서는 service 계층으로 부터 받아온 like의 UUID를 이용해서 쿠키를 생성해주는 역할을 합니다.
현재 방식도 부스 데이터가 적은 서비스를 운영하는데에는 큰 문제가 발생하지 않았던 방법있습니다. 하지만 곰곰히 생각을 해보면 문제점이 있었습니다.
현재는 사용자를 식별하지 않고 좋아요를 식별하는 구조이기 때문에 사용자가 좋아요를 많이 누르게 되면 그만큼 쿠키를 발급받아서 브라우저에 쌓이는 방식입니다. 즉 한 사용자가 5개의 부스에 좋아요를 누르면 5개의 쿠키가 생기게 됩니다. RFC 6265에 따르면 cookie에는 제약사항이 있습니다.
위의 규칙을 적용하면 저희 서비스에서는 50개의 부스에만 좋아요를 할 수 있는 상황이 발생합니다. 교내 축제때에는 부스가 많지 않아 운영시에는 문제가 발생하지 않았지만 이는 확장성이 있는 방식은 아니었습니다. 이 부분을 더 개선할 수 있는 방안을 고민해야겠습니다.