Web/Ktor

[Ktor] Ktor와 Koin을 사용해서 스프링부트 따라잡기

MarrRang 2022. 1. 29. 14:08

최근에 접하게 된 Ktor 프레임워크와 injection(주입)을 도와주는 Koin 라이브러리를 이용해서 기존에 사용했던 스프링 부트 프로젝트를 대체할 수 있도록 공부하기 위해 작성한 게시글입니다.

 

Ktor 자체의 정보도 아직은 많지 않고 정식으로 배우고 정리하는 글이 아니기 때문에 정상적이지 않은 코드와 불편함을 느낄만한 요소들이 있을 수 있습니다. (너그럽게 봐주세요 ㅎㅎ)

 

시리즈 진행상황

시리즈 1. 간단한 Api 호출과 MVC 구조 따라하기, 프로파일 구분하기

 

코드

참고 사이트 : https://ktor.io/docs/welcome.html (Ktor 가이드)

Github : https://github.com/MarrRang/ktor-go-to-lunch/tree/master/src/main/kotlin/com/example

 

GitHub - MarrRang/ktor-go-to-lunch

Contribute to MarrRang/ktor-go-to-lunch development by creating an account on GitHub.

github.com

 

프로젝트 살펴보기

프로젝트 개요

랜덤한 고양이 이미지 데이터를 json 형식으로 반환해주는 CatApi에서 데이터를 받아와서 보여주는 API 작성

프로젝트 스펙

  • Kotlin 1.6.10
  • Ktor 1.6.7
  • Koin 3.1.4

디렉터리 구성

  • routing : 스프링에서 Controller에 해당하는 부분으로 볼 수 있습니다.
  • module : Koin 컨테이너가 관리할 정의들을 모아두는 일종의 공간, 주입할 컴포넌트들이나 모듈들을 정의하고 모아둘 수 있습니다.
  • service : Spring MVC 패턴에서 사용하는 Service와 동일

 

Application.kt

 

  • stopKoin() : 현재 어플리케이션 기동시에는 필요 없습니다. 하지만 테스트시에 여러 Koin 환경을 사용해야 하는 경우 테스트 시작할 때 startKoin()하고 테스트 종료 시에는 stopKoin()해서 환경을 종료시켜주는 용도로 사용합니다.
    혹시나 Koin을 적용하고 이미 Koin이 시작되어 있다는 에러가 발생한다면 stopKoin을 위와 같이 사용할 수도 있습니다.
  • startKoin() : Koin 환경을 실행하면서 등록이 필요한 것들을 이 블락에 작성합니다.
  • HoconApplicationConfig() : Hocon 형식으로 작성된 파일을 읽어서 Config를 가져옵니다. ConfigFactory.load()하면 기본적으로는 resources/application.conf 파일을 읽어옵니다.
  • fileProperties() : 특정 파일에서 프로퍼티를 읽어와서 등록할 수 있습니다. 등록 이후에는 Koin에서 꺼내서 사용할 수 있습니다. 위 코드에서는 Profile별로 프로퍼티를 구분하기 위해서 작성한 코드입니다.
  • modules() : 사용자가 작성한 모듈을 Koin 컨테이너에 등록합니다. 여러 모듈들에서 정의된 Koin 객체들을 등록합니다.
  • routing {} : Ktor에 router를 등록합니다. 여러 router가 생겼을 때를 대비해 하나의 함수(registerRouters)로 묶어두었습니다. 하지만 각각의 router를 정의한 파일에서 등록할 수 있는 방법이 있지 않을까 싶습니다.

 

application.conf

 

ktor에서 제공하는 config들을 등록할 수 있고 사용자가 사용할 config도 등록할 수 있습니다. 위의 예시에서 deployment 같은 경우는 Ktor에서 제공하는 config입니다. (embeddedServer를 사용할 때는 굳이 필요는 없지만 예시로 넣어두었습니다.)

environment.profile 같은 경우는 제가 사용하기 위해 넣은 설정입니다. ${profile}처럼 어플리케이션 구동 시 넣어준 환경변수를 이용할 수 있습니다.

 

application-local.properties

 

Application.kt에서 등록해준 파일입니다. 기존의 Spring에서 프로퍼티를 사용하는 방법과 같고 profile을 파일명에 넣어서 구분했습니다.

 

CatRouter.kt

 

  • by inject() : Koin에 등록해둔 객체를 주입 받는 방법입니다. Spring의 @autowired와 같다고 보입니다.
  • Routing.cat() : Ktor의 Routing에 사용자가 지정한 router를 등록하는 방법입니다. 이후에 Application.routing에서 꺼내서 사용할 수 있습니다.
  • route() : Spring에서 Mapping을 해주듯이 url을 지정하고 하위에서도 get()에도 추가로 지정하여 사용할 수 있습니다.
  • call.respond() : Ktor의 router에서는 return의 형태로 반환을 하지 않고 ApplicationCall 객체를 통해서 응답을 진행합니다. 여러 가지 header, cookie 등을 담을 수 있게 지원하고 있습니다.

 

CatApiService.kt

 

  • httpClient : 생성자 주입을 통해서 주입 받도록 설정했습니다. 주입받는 코드는 뒤에서 Module에 포함되어 있습니다.
  • getKoin().getProperty() : Application.kt에서 Koin에 등록해놓은 프로퍼티를 가져오는 코드입니다.

CatModule.kt

 

  • single : single 블락 안에 작성한 객체는 singleton 방식이 적용되어서 Koin 컨테이너에 등록됩니다. Spring에서 bean을 작성하는 것과 같다고 보입니다. single 이외에도 다양한 방식이 있습니다.
  • CatApiService(get()) : get()은 이전에 생성자 주입 방식으로 작성한 httpClient를 의미합니다. 기존에 HttpClient를 Koin 객체로 등록해두었고 CatApiService의 생성자에 HttpClient를 명시해 두었기 때문에 get()으로 축약하여 사용할 수 있습니다. 단순히 get()이 아닌 직접적으로 명시하는 방법도 있습니다.

ClientConfiguration.kt

 

이 파일은 Module 디렉토리에 정의되어야 하는 것이 맞지만 전체 코드에서 사용할 Config적인 모듈을 구분하기 위해서 Configuration으로 명시했습니다. 여기에서 HttpClient를 Koin 컨테이너에 등록해두었기 때문에 생성자 주입에서 사용할 수 있습니다.

 

정리

전체 코드를 가벼운 설명과 함께 정리해보았습니다. 설명 중 틀린 부분이 분명 있을 수 있으며 제 코드가 정답이라기보다는 여러분들이 Ktor와 Koin을 사용하여 코드 작성 시에 참고하는 용도로 봐주시면 감사하겠습니다.

반응형