Skip to content
This repository has been archived by the owner on May 19, 2024. It is now read-only.

Commit

Permalink
[WEAV-329] 이전 채팅메시지 조회 API 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
waterfogSW committed Apr 13, 2024
1 parent 80a157d commit 35298a2
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.studentcenter.weave.application.chat.port.inbound

import com.studentcenter.weave.domain.chat.entity.ChatMessage
import com.studentcenter.weave.support.common.dto.ScrollRequest
import com.studentcenter.weave.support.common.dto.ScrollResponse
import java.util.UUID

interface GetChatMessage {

fun getScrollList(query: ScrollListQuery): ScrollListResult

data class ScrollListQuery(
val chatRoomId: UUID,
override val next: UUID?,
override val limit: Int
) : ScrollRequest<UUID?>(
next = next,
limit = limit
)

data class ScrollListResult(
override val items: List<ChatMessage>,
override val next: UUID?,
) : ScrollResponse<ChatMessage, UUID?>(
items = items,
next = next,
total = items.size,
)

}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
package com.studentcenter.weave.application.chat.port.outbound

import com.studentcenter.weave.application.chat.port.inbound.GetChatMessage
import com.studentcenter.weave.domain.chat.entity.ChatMessage

interface ChatMessageRepository {

fun save(chatMessage: ChatMessage)

fun getScrollList(query: GetChatMessage.ScrollListQuery): List<ChatMessage>

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.studentcenter.weave.application.chat.service

import com.studentcenter.weave.application.chat.port.inbound.GetChatMessage
import com.studentcenter.weave.application.chat.port.outbound.ChatMessageRepository
import com.studentcenter.weave.domain.chat.entity.ChatMessage
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional

@Service
@Transactional(readOnly = true)
class GetChatMessageService(
private val chatMessageRepository: ChatMessageRepository,
) : GetChatMessage {

override fun getScrollList(query: GetChatMessage.ScrollListQuery): GetChatMessage.ScrollListResult {
val result: List<ChatMessage> = query
.copy(limit = query.limit + 1)
.let { chatMessageRepository.getScrollList(it) }

return GetChatMessage.ScrollListResult(
items = result.take(query.limit),
next = if (result.size > query.limit) result.last().id else null
)
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.studentcenter.weave.bootstrap.chat.api

import com.studentcenter.weave.bootstrap.chat.dto.GetChatMessagesRequest
import com.studentcenter.weave.bootstrap.chat.dto.GetChatMessagesResponse
import com.studentcenter.weave.bootstrap.common.security.annotation.Secured
import io.swagger.v3.oas.annotations.Operation
import io.swagger.v3.oas.annotations.tags.Tag
import org.springframework.http.HttpStatus
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.ResponseStatus

@Tag(name = "ChatMessage", description = "채팅 메시지 API")
@RequestMapping("/api/chat-messages")
interface ChatMessageApi {

@Secured
@Operation(summary = "채팅 메시지 조회")
@GetMapping
@ResponseStatus(HttpStatus.OK)
fun getChatMessages(request: GetChatMessagesRequest): GetChatMessagesResponse

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.studentcenter.weave.bootstrap.chat.controller

import com.studentcenter.weave.application.chat.port.inbound.GetChatMessage
import com.studentcenter.weave.bootstrap.chat.api.ChatMessageApi
import com.studentcenter.weave.bootstrap.chat.dto.GetChatMessagesRequest
import com.studentcenter.weave.bootstrap.chat.dto.GetChatMessagesResponse
import com.studentcenter.weave.bootstrap.chat.dto.GetChatMessagesResponse.Companion.toResponse
import org.springframework.web.bind.annotation.RestController

@RestController
class ChatMessageRestController(
private val getChatMessage: GetChatMessage,
) : ChatMessageApi {

override fun getChatMessages(request: GetChatMessagesRequest): GetChatMessagesResponse {
val (chatRoomId, next, limit) = request.validate()
return GetChatMessage
.ScrollListQuery(chatRoomId, next, limit)
.let { getChatMessage.getScrollList(it) }
.toResponse()
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.studentcenter.weave.bootstrap.chat.dto

import io.swagger.v3.oas.annotations.media.Schema
import java.util.*

@Schema(description = "채팅 메시지 조회 요청")
data class GetChatMessagesRequest(
@Schema(description = "채팅방 ID", example = "123e4567-e89b-12d3-a456-426614174000")
val chatRoomId: UUID?,
@Schema(description = "이전 메시지 조회를 위한 cursor", example = "123e4567-e89b-12d3-a456-426614174000")
val next: UUID?,
@Schema(description = "한번에 조회할 메시지 수", defaultValue = "20", example = "20")
val limit: Int? = 20,
) {

fun validate(): Validated {
requireNotNull(chatRoomId) { "유효하지 않은 채팅방 입니다" }
requireNotNull(limit) { "유효하지 않은 요청입니다"}
require(limit > 0) { "한번에 조회할 메시지 수는 0보다 커야 합니다" }
return Validated(chatRoomId, next, limit)
}

data class Validated(
val chatRoomId: UUID,
val next: UUID?,
val limit: Int,
)

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.studentcenter.weave.bootstrap.chat.dto

import com.studentcenter.weave.application.chat.port.inbound.GetChatMessage
import com.studentcenter.weave.domain.chat.entity.ChatMessage
import io.swagger.v3.oas.annotations.media.Schema
import java.util.*

@Schema(description = "채팅 메시지 목록 조회 응답")
data class GetChatMessagesResponse(
@Schema(description = "채팅 메시지 목록")
val items: List<ChatMessage>,
@Schema(description = "다음 메시지 ID")
val next: UUID?,
@Schema(description = "조회한 메시지 수")
val total: Int,
) {
companion object {
fun GetChatMessage.ScrollListResult.toResponse(): GetChatMessagesResponse {
return GetChatMessagesResponse(
items = this.items,
next = this.next,
total = this.total,
)
}
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.studentcenter.weave.infrastructure.persistence.chat.adapter

import com.studentcenter.weave.application.chat.port.inbound.GetChatMessage
import com.studentcenter.weave.application.chat.port.outbound.ChatMessageRepository
import com.studentcenter.weave.domain.chat.entity.ChatMessage
import com.studentcenter.weave.infrastructure.persistence.chat.enitty.ChatMessageJpaEntity.Companion.toJpaEntity
Expand All @@ -17,4 +18,14 @@ class ChatMessageJpaAdapter(
.also { chatMessageJpaRepository.save(it) }
}

override fun getScrollList(query: GetChatMessage.ScrollListQuery): List<ChatMessage> {
return chatMessageJpaRepository
.getScrollList(
chatRoomId = query.chatRoomId,
next = query.next,
limit = query.limit,
)
.map { it.toDomain() }
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,28 @@ package com.studentcenter.weave.infrastructure.persistence.chat.repository

import com.studentcenter.weave.infrastructure.persistence.chat.enitty.ChatMessageJpaEntity
import org.springframework.data.jpa.repository.JpaRepository
import org.springframework.data.jpa.repository.Query
import org.springframework.stereotype.Repository
import java.util.*

@Repository
interface ChatMessageJpaRepository : JpaRepository<ChatMessageJpaEntity, UUID> {

@Query(
value =
"""
select * from chat_message cm
where cm.room_id = :chatRoomId
and (:next is null or cm.id <= :next)
order by cm.id desc
limit :limit
""",
nativeQuery = true
)
fun getScrollList(
chatRoomId: UUID,
next: UUID?,
limit: Int,
): List<ChatMessageJpaEntity>

}

0 comments on commit 35298a2

Please sign in to comment.