✨ [reactive-app] 상품 조회
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
package me.jiniworld.demohx.application.item.domain
|
||||
|
||||
data class Item(
|
||||
val id: String,
|
||||
val name: String,
|
||||
val price: Int,
|
||||
val stock: Int,
|
||||
)
|
||||
@@ -0,0 +1,9 @@
|
||||
package me.jiniworld.demohx.application.item.port.input
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import me.jiniworld.demohx.application.item.domain.Item
|
||||
|
||||
|
||||
interface GetItemQuery {
|
||||
fun getItems(command: GetItemsCommand): Flow<Item>
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package me.jiniworld.demohx.application.item.port.input
|
||||
|
||||
data class GetItemsCommand(
|
||||
val page: Int,
|
||||
val size: Int,
|
||||
)
|
||||
@@ -0,0 +1,11 @@
|
||||
package me.jiniworld.demohx.application.item.port.output
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import me.jiniworld.demohx.application.item.domain.Item
|
||||
import org.springframework.data.domain.Pageable
|
||||
|
||||
interface LoadItemPort {
|
||||
suspend fun loadItem(id: String): Item?
|
||||
fun loadItems(pageable: Pageable): Flow<Item>
|
||||
fun loadItems(ids: Collection<String>): Flow<Item>
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package me.jiniworld.demohx.application.item.service
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import me.jiniworld.demohx.annotation.UseCase
|
||||
import me.jiniworld.demohx.application.item.domain.Item
|
||||
import me.jiniworld.demohx.application.item.port.input.GetItemQuery
|
||||
import me.jiniworld.demohx.application.item.port.input.GetItemsCommand
|
||||
import me.jiniworld.demohx.application.item.port.output.LoadItemPort
|
||||
import org.springframework.data.domain.PageRequest
|
||||
import org.springframework.data.domain.Sort
|
||||
import org.springframework.transaction.annotation.Transactional
|
||||
|
||||
@Transactional(readOnly = true)
|
||||
@UseCase
|
||||
internal class GetItemService(
|
||||
private val loadItemPort: LoadItemPort,
|
||||
): GetItemQuery {
|
||||
|
||||
override fun getItems(command: GetItemsCommand): Flow<Item> {
|
||||
return loadItemPort.loadItems(
|
||||
PageRequest.of(command.page, command.size, Sort.by(
|
||||
Sort.Order.desc("id")))
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package me.jiniworld.demohx.persistence.item
|
||||
|
||||
import org.springframework.data.annotation.CreatedDate
|
||||
import org.springframework.data.annotation.Id
|
||||
import org.springframework.data.annotation.LastModifiedDate
|
||||
import org.springframework.data.mongodb.core.mapping.Document
|
||||
import java.time.LocalDateTime
|
||||
|
||||
@Document("item")
|
||||
internal class ItemDocument(val name: String, val price: Int, var stock: Int) {
|
||||
@Id
|
||||
var id: String = ""
|
||||
|
||||
@CreatedDate
|
||||
var createdAt: LocalDateTime = LocalDateTime.now()
|
||||
|
||||
@LastModifiedDate
|
||||
var updatedAt: LocalDateTime? = null
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package me.jiniworld.demohx.persistence.item
|
||||
|
||||
import me.jiniworld.demohx.application.item.domain.Item
|
||||
|
||||
internal object ItemMapper {
|
||||
|
||||
fun mapToDomainEntity(doc: ItemDocument): Item {
|
||||
return Item(doc.id, doc.name, doc.price, doc.stock)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package me.jiniworld.demohx.persistence.item
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.map
|
||||
import me.jiniworld.demohx.annotation.PersistenceAdapter
|
||||
import me.jiniworld.demohx.application.item.domain.Item
|
||||
import me.jiniworld.demohx.application.item.port.output.LoadItemPort
|
||||
import org.springframework.data.domain.Pageable
|
||||
|
||||
@PersistenceAdapter
|
||||
internal class ItemPersistenceAdapter(
|
||||
private val itemRepository: ItemRepository,
|
||||
): LoadItemPort {
|
||||
|
||||
override suspend fun loadItem(id: String): Item? {
|
||||
return itemRepository.findById(id)
|
||||
?.let { ItemMapper.mapToDomainEntity(it) }
|
||||
}
|
||||
|
||||
override fun loadItems(pageable: Pageable): Flow<Item> {
|
||||
return itemRepository.findAllBy(pageable)
|
||||
.map { ItemMapper.mapToDomainEntity(it) }
|
||||
}
|
||||
|
||||
override fun loadItems(ids: Collection<String>): Flow<Item> {
|
||||
return itemRepository.findAllById(ids)
|
||||
.map { ItemMapper.mapToDomainEntity(it) }
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package me.jiniworld.demohx.persistence.item
|
||||
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.data.repository.kotlin.CoroutineCrudRepository
|
||||
import org.springframework.stereotype.Repository
|
||||
|
||||
@Repository
|
||||
internal interface ItemRepository: CoroutineCrudRepository<ItemDocument, String> {
|
||||
fun findAllBy(pageable: Pageable): Flow<ItemDocument>
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package me.jiniworld.demohx.web.item
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation
|
||||
import io.swagger.v3.oas.annotations.tags.Tag
|
||||
import me.jiniworld.demohx.annotation.WebAdapter
|
||||
import me.jiniworld.demohx.application.item.port.input.GetItemQuery
|
||||
import me.jiniworld.demohx.application.item.port.input.GetItemsCommand
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@WebAdapter
|
||||
@Tag(name = "item", description = "상품")
|
||||
@RestController
|
||||
@RequestMapping("/v1/items")
|
||||
internal class GetItemController(
|
||||
private val getItemQuery: GetItemQuery,
|
||||
) {
|
||||
@Operation(summary = "삼품 목록")
|
||||
@GetMapping("")
|
||||
fun getItems(
|
||||
@RequestParam(value = "page", required = false, defaultValue = "0") page: Int,
|
||||
@RequestParam(value = "size", required = false, defaultValue = "10") size: Int,
|
||||
) = getItemQuery.getItems(GetItemsCommand(page = page, size = size))
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user