Skip to content

[IDLE-561] 웹소켓 직렬화/역직렬화 이슈 해결 및 채팅방 생성 케이스 보완#268

Merged
mjj111 merged 3 commits intodevelopfrom
feat/IDLE-561
Apr 11, 2025
Merged

[IDLE-561] 웹소켓 직렬화/역직렬화 이슈 해결 및 채팅방 생성 케이스 보완#268
mjj111 merged 3 commits intodevelopfrom
feat/IDLE-561

Conversation

@mjj111
Copy link
Copy Markdown
Member

@mjj111 mjj111 commented Apr 11, 2025

1. 📄 Summary

  • LocalDateTime 직렬화 이슈 해결
  • WebSocket Payload 역직렬화 문제 해결
  • 채팅방 생성 시 기존에 존재하는 방이면 ID 반환하도록 로직 수정

2. 💡 알게된 점, 궁금한 점

Java에서 record를 DTO로 사용할 땐 WebSocket에서 직렬화/역직렬화 문제가 발생하지 않았지만,
Kotlin의 data class를 사용하니 역직렬화 오류가 발생했습니다.

이는 기본적으로 자바의 Record는 기본 생성자를 컴파일 시점에서 생성해주지만,
Kotlin의 data class는 기본 생성자(default constructor) 가 명시적으로 존재하지 않으며!
null-safety, val/var, companion 등 다양한 기능을 포함해서 동작합니다.

이에따라 Jackson이 역직렬화 시 적절한 생성자나 프로퍼티 주입 정보를 찾지 못해 예외를 발생시키게 됐습니다.

따라서 @JsonCreator와 @JsonProperty를 사용해 생성자 기반 역직렬화 방식으로 명확히 지정해주거나,
jackson-module-kotlin을 반드시 등록해줘야 안정적으로 처리할 수 있다는 걸 알게 되었습니다.

Summary by CodeRabbit

  • New Features

    • 채팅방 생성 로직이 개선되어, 동일 조건의 채팅방이 이미 존재할 경우 해당 채팅방을 재사용합니다.
  • Refactor

    • 메시지 전송 설정이 개선되어 날짜 포맷 및 메시지 변환 처리가 향상되었습니다.
    • 채팅 메시지 요청 데이터의 JSON 직렬화 방식이 개선되어 안정적인 데이터 처리가 가능합니다.

@mjj111 mjj111 added the 🎯리팩토링 리팩토링 및 고도화 이슈 label Apr 11, 2025
@mjj111 mjj111 self-assigned this Apr 11, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 11, 2025

Walkthrough

이 PR에서는 채팅방 생성 로직, 검색 기능, 웹소켓 설정, 및 데이터 직렬화 관련 클래스에 변경이 이루어졌습니다.

  • ChatRoomService: 기존에 단순 생성 후 저장하던 채팅방 생성 로직을, 동일한 carerId와 centerId를 가진 채팅방이 이미 존재하는지 먼저 확인한 후, 존재하면 해당 채팅방의 ID를 반환하도록 변경하였습니다.
  • ChatRoomRepository: carerId와 centerId를 기준으로 채팅방을 검색할 수 있는 findByCarerIdAndCenterId 메소드를 추가하였습니다.
  • WebSocketConfig: MessageConverter 구성과 관련하여 파라미터 타입 및 Jackson ObjectMapper 설정 방식이 수정되었습니다.
  • ReadChatMessagesReqeust: JSON 직렬화/역직렬화를 명시하기 위해 Jackson 어노테이션이 추가되었습니다.

Changes

파일 변경 요약
idle-application/.../ChatRoomService.kt create 함수 로직 변경: 기존 채팅방 존재 여부 확인 후, 존재 시 기존 ID 반환, 부재 시 새 생성
idle-domain/.../ChatRoomRepository.kt 새로운 메소드 findByCarerIdAndCenterId 추가: carerId와 centerId 기반 채팅방 검색 기능 도입
idle-presentation/.../WebSocketConfig.kt configureMessageConverters 수정: 파라미터 타입 변경 및 MappingJackson2MessageConverter 구성 개선
idle-support/transfer/.../ReadChatMessagesReqeust.kt 데이터 클래스에 Jackson 어노테이션(@JsonCreator, @JsonProperty) 추가하여 JSON 직렬화/역직렬화 처리 명시

Sequence Diagram(s)

sequenceDiagram
    participant U as 사용자
    participant CRS as ChatRoomService
    participant CRR as ChatRoomRepository

    U->>CRS: create(carerId, centerId) 호출
    CRS->>CRR: findByCarerIdAndCenterId(carerId, centerId) 호출
    alt 채팅방 존재
        CRR-->>CRS: 기존 ChatRoom 반환
        CRS-->>U: 기존 ChatRoom ID 반환
    else 채팅방 부재
        CRS->>CRR: 새 ChatRoom 저장 호출
        CRR-->>CRS: 새 ChatRoom ID 반환
        CRS-->>U: 새 ChatRoom ID 반환
    end
Loading

Tip

⚡💬 Agentic Chat (Pro Plan, General Availability)
  • We're introducing multi-step agentic chat in review comments and issue comments, within and outside of PR's. This feature enhances review and issue discussions with the CodeRabbit agentic chat by enabling advanced interactions, including the ability to create pull requests directly from comments and add commits to existing pull requests.
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/config/WebSocketConfig.kt (1)

39-47: 애플리케이션 전체에서 일관된 ObjectMapper 설정 확인 필요

이 클래스에서 ObjectMapper 구성을 변경했지만, 애플리케이션의 다른 부분에서도 동일한 설정이 필요할 수 있습니다. 애플리케이션 전체에서 ObjectMapper 구성이 일관되게 유지되는지 확인하는 것이 좋습니다. 가능하다면 Bean으로 등록하여 재사용하는 것을 고려해보세요.

- val objectMapper = ObjectMapper()
-     .registerModule(JavaTimeModule())
-     .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
- 
- val converter = MappingJackson2MessageConverter()
- converter.objectMapper = objectMapper
+ // 애플리케이션 전체에서 사용할 ObjectMapper Bean 주입받기
+ @Autowired
+ private lateinit var objectMapper: ObjectMapper
+ 
+ // 메서드 내에서
+ val converter = MappingJackson2MessageConverter()
+ converter.objectMapper = objectMapper

관련하여 애플리케이션에서 ObjectMapper를 Bean으로 등록하는 구성 클래스를 만들 수 있습니다:

@Configuration
class JacksonConfig {
    @Bean
    fun objectMapper(): ObjectMapper {
        return ObjectMapper()
            .registerModule(JavaTimeModule())
            .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
    }
}
idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/chat/ReadChatMessagesReqeust.kt (1)

7-10: JSON 직렬화/역직렬화 문제 해결을 위한 적절한 어노테이션

Kotlin 데이터 클래스에 @JsonCreator@JsonProperty 어노테이션을 추가하여 웹소켓 통신 시 발생할 수 있는 직렬화/역직렬화 문제를 해결한 것은 좋은 접근입니다. PR 목적에 부합하는 변경입니다.

다만, 9번 줄에서 @JsonProperty("opponentId")val opponentId 사이에 공백이 누락되어 있습니다. 가독성을 위해 공백을 추가하는 것이 좋겠습니다.

-    @JsonProperty("opponentId")val opponentId: UUID
+    @JsonProperty("opponentId") val opponentId: UUID
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6b0a45a and 09f6044.

📒 Files selected for processing (4)
  • idle-application/src/main/kotlin/com/swm/idle/application/chat/domain/ChatRoomService.kt (1 hunks)
  • idle-domain/src/main/kotlin/com/swm/idle/domain/chat/repository/ChatRoomRepository.kt (1 hunks)
  • idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/config/WebSocketConfig.kt (2 hunks)
  • idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/chat/ReadChatMessagesReqeust.kt (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build and analyze
🔇 Additional comments (8)
idle-presentation/src/main/kotlin/com/swm/idle/presentation/chat/config/WebSocketConfig.kt (5)

3-5: 적절한 직렬화를 위한 필수 모듈 임포트 추가

JavaTimeModule 및 SerializationFeature를 가져오는 임포트를 추가한 것은 LocalDateTime과 같은 Java 시간 클래스의 직렬화/역직렬화 문제를 해결하기 위한 적절한 접근 방식입니다.


35-35: 메서드 시그니처 변경에 대한 주의

메서드 매개변수 타입을 MutableList<MessageConverter>에서 MutableList<MessageConverter?>로 변경하셨네요.
이는 null 가능한 MessageConverter를 허용하기 위한 것으로 보이지만, 코드에서 null 체크를 하지 않고 있습니다. 실제로 null 값이 전달될 가능성이 있는지 확인해보세요.


37-37: 더 깔끔한 코드 스타일 적용

이전의 also 블록 대신 직접 할당 방식을 사용하여 코드가 더 간결해졌습니다.


39-41: LocalDateTime 직렬화 문제 해결

ObjectMapper에 JavaTimeModule을 등록하고 WRITE_DATES_AS_TIMESTAMPS를 비활성화한 것은 LocalDateTime의 직렬화 문제를 효과적으로 해결합니다. 이로써 날짜가 타임스탬프가 아닌 ISO 형식으로 올바르게 직렬화됩니다.


43-47: 코드 구조 개선

이전 구현에서 인라인 also 블록을 사용하던 방식에서 명시적인 설정 방식으로 변경하여 코드의 가독성과 유지보수성이 향상되었습니다.

idle-domain/src/main/kotlin/com/swm/idle/domain/chat/repository/ChatRoomRepository.kt (1)

14-14: 적절한 레포지토리 메서드 추가

findByCarerIdAndCenterId 메서드 추가는 Spring Data JPA 메서드 명명 규칙을 잘 따르고 있으며, 채팅방 생성 로직 개선에 필요한 적절한 기능입니다. 반환 타입이 ChatRoom?로 설정되어 있어 해당 조합의 채팅방이 없을 경우를 고려하고 있습니다.

idle-application/src/main/kotlin/com/swm/idle/application/chat/domain/ChatRoomService.kt (1)

13-16: 채팅방 생성 로직 개선

기존에 항상 새로운 채팅방을 생성하던 로직에서, 동일한 carerId와 centerId 조합의 채팅방이 이미 존재하는지 확인 후 존재하면 해당 채팅방 ID를 반환하도록 변경한 것은 중복 채팅방 생성을 방지하는 좋은 개선입니다. Elvis 연산자(?:)를 사용하여 간결하게 구현한 점도 좋습니다.

idle-support/transfer/src/main/kotlin/com/swm/idle/support/transfer/chat/ReadChatMessagesReqeust.kt (1)

3-4: Jackson 어노테이션 적절히 추가

웹소켓 직렬화/역직렬화 이슈 해결을 위해 필요한 Jackson 어노테이션을 추가한 것은 적절합니다.

@sonarqubecloud
Copy link
Copy Markdown

@mjj111 mjj111 merged commit bb1311d into develop Apr 11, 2025
5 checks passed
@mjj111 mjj111 deleted the feat/IDLE-561 branch April 11, 2025 12:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🎯리팩토링 리팩토링 및 고도화 이슈

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant