23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
Kotlin언어을 개발했고, 개발 환경 IDE로 유명한 Jetbrain사에서 개발한 경량 웹 프레임워크인 Ktor를 이용한 간단한 REST-API서버 개발 소개 글입니다.
Ktor는 Pivotal사의 Spring 프레임워크에 비해서 상당히 경량화된 프레임워크(AOP,DI같은 고급(?) 기능들은 지원하지 않습니다.)이고, 코틀린과 코루틴에 대한 기본 지식이 있다면 러닝 커브가 낮습니다.
REST API서버를 실행하기 위한 기본적인 프로젝트 셋업 및 상용 배포를 위한 설정(배포 환경에 따른 설정 파일 분리, 데이터독 로그 연동을 위한 설정 등등..)위주로 알아 보겠습니다.
Ktor는 다음과 같은 독특한 특징을 가지고 있습니다.
Coroutine 기반의 비동기 처리
Ktor는 Kotlin의 코루틴을 활용하여 비동기 처리를 기본적으로 지원합니다. 이는 성능을 향상시키고, 리소스 사용을 최적화하는 데 도움이 됩니다.
멀티플랫폼 지원
Ktor는 Kotlin의 멀티플랫폼 기능을 활용하여 JVM뿐만 아니라 Kotlin/Native, Kotlin/JS 등 다양한 플랫폼에서 사용할 수 있습니다.
이는 다양한 환경에서의 애플리케이션 개발을 용이하게 합니다.
간단한 설정과 경량성
Ktor는 설정이 간편하고 경량 서버로 설계되어 빠르게 구동할 수 있습니다.
이는 빠른 배포와 유연한 확장이 필요한 현대적 MSA(Microservices Architecture) 구조에 적합합니다.
위와 같이 좋은 특징을 가지고 있지만, 아직 아쉬운 점도 많은 것이 사실 입니다.
작은 Ecosystem
Ktor의 ecosystem가 개발자 커뮤니티는 아직 한참 확장 중입니다.
Spring과 같이 오랜 기간 개발된 프레임워크에 커뮤니티의 성숙도나, 지원하는 third-party 패키지들이 아직 부족합니다.
성숙도
출현한지 얼마 되지 않은 프레임워크인 관계로 Best Practice나 몇몇 기능들은 아직 아쉬운 부분들이 있습니다.
아쉬운점들도 있지만, 저같은 경우 위의 특징들중 첫번째와 3번째 특징 때문에 관심을 가지게 되었고,
팀에서 마침 AI Divergency프로젝트 때문에 MAS 컴포넌트 추가가 필요해서 프로젝트 셋업 작업을 진행 했고, 작업후 내용 정리 및 공유 차원에서 글을 작성 하는 중입니다.
Ktor프로젝트 셋업을 위해서는 초기 프로젝트 생성용 싸이트를 이용하는 방법과 IntelliJ IDE를 이용하는 방법이 있습니다
(둘 중에 어떤걸 선택해도 비슷한 결과를 얻기 때문에 저는 첫번째 방법을 이용해서 생성하도록 하겠습니다)
ktor에서 공식적으로 제공하는 프로젝트 생성 싸이트 https://start.ktor.io/settings 에 접속 합니다.
이 싸이트에 접속해서 해야할 일은 크게 3가지 입니다.
Project Artifact명 입력,
사용할 플러그인들 선택,
다운로드 클릭
첫번째와 세번째에 대한 설명은 생략하도록 하겠습니다.(적절하게 입력해 주세요)
두 번째 플러그인들 선택에 대해서 알아 보도록 하겠습니다.
(플러그인이란 용어가 생소할수 있는데, 스프링에 익숙한 개발자분들한테 친숙한 용어로 풀어 쓴다면, Configuration 정도로 이야기 할수 있을꺼 같습니다.)
REST API서버 구현을 위해서 필요한 기본 플러그인들 선택(주관적 취향임!!!)
Routing
OpenAPI
Call Logging
CallId
Content Negotiation
Gson
Shutdown URL
이외에도 DefaultHeaders, Forwared Headers, Static Content, CORS, DoubleReceive등등도 나중에 필요한 경우가 있을수 있을꺼 같지만,
우선 단순한 REST API서버 개발을 목표로 한다면 위의 목록만으로도 충분 합니다.
플러그인 선택까지 마친 후 download를 틀릭하면 압축된 프로젝트 초기 파일이 다운로드 됩니다.
이 파일을 적당한 위치에서 압축을 해재하신 후 IDE로 open하면 개발할 준비는 완료 되었습니다.
초기 프로젝트 파일에도 샘플 코드가 포함되어 있기 때문에 압축 해재 후 바로 서버를 Build&Run해 볼수 있습니다.
./gradlew clean build -x test
java -jar ./build/libs/com.sample.ktor_example-all.jar
위와 같이 서버를 빌드한 후 기동하게 되면 8080서버로 접속이 가능 합니다.
main함수가 있고 Application타입의 확장 함수로 Application.module()함수가 정의 되어 있습니다.
main함수는 ktor.netty서버 엔진을 기동하는 호출만 하고, 별다른 일을 하지 않습니다.
앞에서 선택한 플러그인들을 초기화하는 함수인 Application.module함수와의 연결 고리가 보이지 않습니다.
이부분은 코드가 아니라 설정 파일에 기술되어 있습니다.
생성된 코드를 살펴 보변, 선택한 플러그인들을 차례 차례로 초기화 하기 위해서 확장 함수들을 생성 했고, module함수에서 하나씩 호출하는것을 알수 있습니다.
configureSerialization함수를 하나 살펴 보도록 하겠습니다.
ContentNegotiation을 설치하고 테스트를 위한 /json/gson endpoint를 하나 추가 했습니다. json일 경우 gson을 이용해서 serialize하는데,
Seialize시 사용한 Gson serialize에 대한 custom설정이 필요한 경우 아래 처럼 코드 추가가 가능 합니다.
아래와 같이 간단한 Employee 객체에 대한 기본 CRUD API를 ktor스타일로 추가해 보는 예시 입니다.
(아직 DB연동 전이므로 간단하게 Employee DTO를 정의하고 companion object에 map기반으로 repository를 구현했습니다)
Route DSL로 작성된 employee관련 API 라우트들을 Application에 등록하는 코드를 아래 처럼 추가해야 한다.
curl호출 예시
curl -v -X POST http://localhost:8080/employees -H 'Content-Type: application/json' -d '{ "name": "Kim", "age": 30, "deptName": "IT" }'
curl -v -X GET http://localhost:8080/employees/Kim
curl -v -X PUT 'http://localhost:8080/employees/Kim?deptName=HR' -H 'Content-Type: application/json'
curl -v -X GET http://localhost:8080/employees/Kim
curl -v -X DELETE 'http://localhost:8080/employees/Kim'개발/스테이지/상용 으로 환경이 분리된 개발 환경에서 서버를 개발하려면 필수적으로 환경별로 설정 파일을 분리해서 관리 할수 있어야 합니다.
스프링 프레임워크와 비슷하게 application.yaml기본 설정 파일에 환경별 설정 파일을 override할수 있는 방법을 ktor프레임워크도 제공 합니다.
ktor프레임워크에서 설정파일 값들에 대한 접근 방법 및 override방식에 대해서 알아 보도록 하겠습니다.
프로젝트 셋업에 의해서 초기 생성된 파일들을 보면 src/main/resources에 application.yaml파일을 확인 할수 있습니다.
앞에서 살펴본 Gson serializer초기화시 pretty print 옵션을 설정 파일로 제어 하기 위해서 아래 처럼 설정 항목을 추가 할수 있습니다.
Gson Serializer초기화시 설정 파일 값 반영을 위해 아래 처럼 코드를 수정 합니다.
기본 설정 파일은 application.yaml파일의 값을 환경(local|dev|stg|prd)별로 override하는 방법에 대해서 알아 봅시다.
우선 override할 로컬 설정 파일을 src/main/resources디렉토리에 아래와 같은 application-local.yaml 파일을 생성 합니다.
빌드 후 실행시 다음과 같이 옵션을 설정 합니다.
java -jar ./build/libs/com.sample.ktor_example-all.jar -config=application.yaml -config=application-local.yaml
애플리케이션을 개발하다 보면 환경 별로 설정 값 override만큼 자주 필요한 기능이 환경별 로그 설정 파일 분리 입니다.
logback을 사용할때 로그 설정 파일을 환경별로 분리 하는 방법에 대해서 알아 봅니다.
src/main/resources디렉토리에 사용할 환경별로 설정 파일을 생성 합니다. 저는 우선 아래 처럼 logback-local.xml설정 파일을 추가 했습니다.
빌드 후 실행시 다음과 같이 옵션을 설정 합니다.
java -Dlogback.configurationFile=logback-local.xml -jar ./build/libs/com.sample.ktor_example-all.jar -config=application.yaml -config=application-local.yaml
애플리케이션 설정은 override하는 방식이지만, log설정파일은 환경에 맞는 설정 파일을 지정하는 방식입니다.
데이터 독 로그 연동시 로컬에서 처럼 평문으로 포맷팅을 하게 되면 원하는 출력 결과를 얻을수 없습니다.
아래 처럼 logstash encoder를 이용해서 json형태로 로그를 출력 해야 합니다.
logback에서 json으로 메시지를 encoding하게 하기 위해서 build.gradle.kts에 logstash encoder dependency를 아래 처럼 추가 합니다.
logback-dev.xml 설정 파일 생성
실행하기
java -Dlogback.configurationFile=logback-dev.xml -jar ./build/libs/com.sample.ktor_example-all.jar -config=application.yaml -config=application-local.yaml
local과는 다르게 콘솔에 출력되는 메시지가 평문이 아닌 json 객체 형태임을 확인 할수 있습니다.
아래 처럼 애플리케이션 Logger를 정의해서 사용합니다.
추가한 AppLog Logger를 이용해서 로그 출력해 보기.
아주 간단하게 Ktor기반의 프로젝트를 생성하고, CRUD API를 추가해보고,
상용 환경까지 배포를 고려한 애플리케이션 설정 및 로그 설정을 환경 별로 분리하고 실행 시키는 방법에 대해서 살펴 보았습니다.
많이 짧은 분량이지만, 아주 간결한 Kotlin/Ktor의 조합에 이끌리신다면 https://ktor.io/docs/welcome.html 페이지를 방문하셔서 하나 하나 따라가 보시길 권하면서 글을 마칩니다.
두서 없는 글을 읽어 주셔서 감사합니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.