티스토리 뷰
반응형
서비스 만들기
CustomerService를 만들었습니다.
interface CustomerService {
fun getCustomer(id: Int): Mono<Customer>
}
CustomerRepository에 아래의 코드를 추가하였습니다.
@Repository
class CustomerRepository (private val template: ReactiveMongoTemplate) {
...
fun findById(id: Int) = template.findById<Customer>(id)
}
그리고 impl 클래스를 만들었습니다.
@Component
class CustomerServiceImpl(private val customerRepository: CustomerRepository) : CustomerService {
override fun getCustomer(id: Int): Mono<Customer> = customerRepository.findById(id)
}
GET
CustomerHandler 클래스를 만들고 get 처리 코드를 작성하였습니다.
@Component
class CustomerHandler(private val customerService: CustomerService) {
fun get(serverRequest: ServerRequest) =
customerService.getCustomer(serverRequest.pathVariable("id").toInt())
.flatMap { ok().body(fromObject(it)) }
.switchIfEmpty(status(HttpStatus.NOT_FOUND).build())
}
그리고 CustomerRouter 클래스를 만들어 HTTP GET 요청 처리를 하였습니다.
@Component
class CustomerRouter(private val customerHandler: CustomerHandler) {
@Bean
fun customerRouters() = router {
"/customer".nest {
GET("/{id}", customerHandler::get)
}
}
}
실행하고 요청을 하면 아래의 결과를 얻을 수 있습니다.
// http://localhost:8081/customer/2
{
"id": 2,
"name": "Leaf"
}
POST
아래와 같이 POST를 생성합니다.
interface CustomerService {
...
fun createCustomer(customer: Mono<Customer>) : Mono<Customer>
}
@Component
class CustomerServiceImpl(private val customerRepository: CustomerRepository) : CustomerService {
...
override fun createCustomer(customer: Mono<Customer>): Mono<Customer> = customerRepository.create(customer)
}
@Component
class CustomerHandler(private val customerService: CustomerService) {
...
fun create(serverRequest: ServerRequest) =
customerService.createCustomer(serverRequest.bodyToMono()).flatMap {
created(URI.create("/customer/${it.id}")).build()
}
}
@Component
class CustomerRouter(private val customerHandler: CustomerHandler) {
@Bean
fun customerRouters() = router {
"/customer".nest {
...
POST("/", customerHandler::create)
}
}
}
그리고 아래 값을 POST 하면
// http://localhost:8081/customer/
{
"id" : 4,
"name" : "user1"
}
DB에 값이 들어온 것을 확인할 수 있습니다.
DELETE
interface CustomerService {
...
fun deleteCustomer(id: Int): Mono<Boolean>
}
@Component
class CustomerServiceImpl(private val customerRepository: CustomerRepository) : CustomerService {
...
override fun deleteCustomer(id: Int): Mono<Boolean> = customerRepository.deleteById(id).map { it.deletedCount > 0 }
}
Mongo<DeleteResult> 객체를 Mongo<Boolean>으로 매핑했습니다.
DeleteResult 객체에는 컬렉션에서 삭제된 객체 수를 가진 속성이 포함되어 있습니다. 따라서 deletedCount가 0보다 크면 삭제된 것입니다.
@Repository
class CustomerRepository (private val template: ReactiveMongoTemplate) {
...
fun deleteById(id: Int) = template.remove<Customer>(Query(where("_id").isEqualTo(id)))
}
위 코드에서는 Query 객체와 where 객체를 사용해서 id 값을 검색하였습니다.
@Component
class CustomerHandler(private val customerService: CustomerService) {
...
fun delete(serverRequest: ServerRequest) =
customerService.deleteCustomer(serverRequest.pathVariable("id").toInt()).flatMap {
if (it) ok().build()
else status(HttpStatus.NOT_FOUND).build()
}
}
flatMap을 사용해 받아온 Boolean 값으로 서비스를 호출했습니다.
마지막으로 라우터를 추가해줍니다.
@Component
class CustomerRouter(private val customerHandler: CustomerHandler) {
@Bean
fun customerRouters() = router {
"/customer".nest {
...
DELETE("/{id}", customerHandler::delete)
}
}
}
아래의 요청을 DELETE로 보내면 DB에서 데이터가 삭제된 것을 확인할 수 있습니다.
// http://localhost:8081/customer/4
검색
interface CustomerService {
...
fun findCustomer(nameFilter: String): Flux<Customer>
}
@Component
class CustomerServiceImpl(private val customerRepository: CustomerRepository) : CustomerService {
...
override fun findCustomer(nameFilter: String): Flux<Customer> = customerRepository.findCustomer(nameFilter)
}
@Repository
class CustomerRepository (private val template: ReactiveMongoTemplate) {
...
fun findCustomer(nameFilter: String) = template.find<Customer>(Query(where("name").regex(".*$nameFilter.*", "i")))
}
정규표현식을 사용해서 nameFilter에 따른 고객이 검색되도록 하였습니다.
@Component
class CustomerHandler(private val customerService: CustomerService) {
...
fun search(serverRequest: ServerRequest) =
ok().body(customerService.findCustomer(serverRequest.queryParam("nameFilter").orElse("")), Customer::class.java)
}
@Component
class CustomerRouter(private val customerHandler: CustomerHandler) {
@Bean
fun customerRouters() = router {
...
"/customers".nest {
GET("/", customerHandler::search)
}
}
}
아래의 URL로 요청을 하면 아래의 결과를 얻을 수 있습니다.
http://localhost:8081/customers?nameFilter=Im
[
{
"id": 1,
"name": "ImLeaf"
},
{
"id": 3,
"name": "ImTae",
"telephone": {
"countryCode": "+82",
"telephoneNumber": "12341234"
}
}
]
반응형
'알려주는 이야기 > 스프링 부트' 카테고리의 다른 글
Spring Boot - MongoDB [ Reactive Repository ] (0) | 2020.09.16 |
---|---|
Spring Boot - MongoDB [ 프로젝트 세팅 ] (0) | 2020.09.16 |
Spring Boot - MongoDB [ 설치 및 사용 방법 ] (0) | 2020.09.16 |
Spring Boot - Reative Rest Api [ 오류 처리 ] (0) | 2020.09.09 |
Spring Boot - Reative Rest Api [ 함수형 ] (0) | 2020.09.09 |
댓글