티스토리 뷰

반응형

서비스 만들기

 

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"
    }
  }
]
반응형
댓글