Open khs960616 opened 3 years ago
변경 이유 : 화면단과 연동하였을 때, 기존에 방이 만들어지지 않은 사용자 간의 DM에서는 OpenRoom이 먼저 만들어진 이후 로그가 쌓여야합니다. 채팅방을 생성하는 UI를 따로 구성할 것이 아니라면 별도의 엔드포인트를 두어 채팅방을 생성하는 것은 차후 다수의 그룹채팅을 구현할 것이 아니면 불필요해보입니다.
질문에 두가지 포인트가 섞여있는듯 해서 이해한대로 아래와같이 두가지로 나눠서 작성하겠습니다😀
1. OpenRoomId 의 pk로 roomId만 사용하지 않고 roomId, userId의 복합키로 구성한 이유
open_room 테이블의 모습입니다.
1번유저와 3번유저가 채팅을 할 경우 두 유저는 String roomId: "1-3" 이라는 같은 채팅방을 사용합니다. 채팅방은 하나인데 해당 채팅방을 사용중인 유저는 둘이므로 같은 roomId값을 가진 두개의 row로 표현이됩니다. 따라서 roomId만으로는 pk를 구성할 수 없습니다. 즉 primary key (roomId, userId) 의 설정이 필요합니다.
1:1채팅이 아닌 그룹채팅으로 확장시에는, 예를들어 1,3,4번유저가 그룹채팅을 할 경우엔 room_id: "1-3-4", user_id: 1 , ~~~ , room_name: "단톡방ㅎㅎ" room_id: "1-3-4", user_id: 3 , ~~~ , room_name: "단톡방ㅎㅎ" room_id: "1-3-4", user_id: 4 , ~~~ , room_name: "단톡방ㅎㅎ" open_room 테이블에 이런식으로 세 row가 구성될 수 있습니다.
즉 그룹채팅으로 확장시 roomId값만 적절한 규칙으로 통일시켜주면 확장이 가능하며, 그룹채팅 확장성을 고려하지 않더라도 roomId 단독으로 pk가 될 수 없습니다.
아래 chat_log 테이블 구조와 함께 확인하면 더 구조 이해가 쉬울 수도 있습니다.
서비스에서는 _select ~~ from chat_log where roomid = "1-3"; 이런 쿼리로, 유저기준 채팅기록이 아닌 한 채팅방 기준 채팅기록을 불러오게됩니다.
2. 채팅방 생성 api의 필요성 우선 카톡으로 받은 동영상을 봤을때, 좌측 '다이렉트 메시지' 를 클릭시 그 아래로 채팅방 리스트가 드롭다운 되는 UI로 구성한 것으로 보입니다.
채팅방 로그를 얻어올 때, 채팅방이 없다면 채팅방을 먼저 생성한다. '채팅방을 생성하는 UI를 따로 구성할 것이 아니라면' <- 이 두 부분이 의문인데 혹시 모든 유저에대한 채팅방이 항시 채팅방 리스트에 드롭다운 되게끔 고려한것은 아닌지? 돌이켜보니 이 부분에 대한 논의가 부족했던것 같습니다.
아래는 채팅기능 프로토타입 구성 당시의 생각입니다. 그룹채팅을 고려하지 않더라도, 모든 유저와의 채팅방이 항상 채팅방 리스트에 마련되어있으면 유저 수가 200명일땐 200개의 리스트가 드롭다운 되게 됩니다. 때문에 화면에 표시되는 채팅방은
유저는 화면에 표시되지 않길 원하는 채팅방을 x버튼이나 나가기 같은 UI 요소를 클릭해 화면에서 제거할 수 있습니다. (채팅 기록이 날아가진 않습니다. 채팅중인 채팅방 리스트에 보이지 않게 할 뿐입니다.)
DB의 open_room 테이블은 오로지 '위 두 경우에 해당되어 사용자 화면에 붙어있어야 할 채팅방 리스트' 를 관리하기 위한 테이블 입니다. 위에서 말한 x버튼이나 나가기 등을 클릭시 open_room 테이블의 1 row가 delete 되어야 합니다. 컨트롤러에 open_room에 대한 DELETE API가 아직 구성되어있지 않은데, 이 흐름으로 사용시 추가 필요할 듯 싶습니다.
정리하자면
잘 설명이 됐는지 모르겠습니다. 단순히 당시의 구성 이유를 적은것으로, 더 나은 방법이 있으면 수정하는게 바람직할 것 같습니다.
OpenRoomId 복합키 구성에서 userId가 들어가는 것은 차후 어떤 서비스 확장 관련해서 이유가 따로 있는 것인지? 그냥 roomId로만 하면 문제되는 부분이 있을지 검토 부탁드립니다. 단순 DM 기능만을 생각했을 때는 별도의 문제가 없을 것 같습니다.
프론트단과 연동하며 일부 수정해서 사용한 내용입니다. 검토후 문제 없으면 메인과 합치겠습니다. 위 문제 관련해서 roomId만 사용해도 된다면 1번 사항은 기존의 코드를 유지합니다.
@GetMapping(value="/user/{userId}/room/{roomId}/chat-logs")
public List getChatLogs(Long userId, String roomId) {
/**
*/ OpenRoom openRoom = openRoomRepo.findByOpenRoomID_RoomId(roomId); if(openRoom == null) { createDirectMessageRoom(userId, roomId); } List chatLogs = chatLogRepo.findByRoomIdOrderByLogNo(roomId);
}