채용 공고 지원 자격에 Ktor가 있었다!
처음 보자마자 뭘까??? 하고 궁금하게 되었다.
그래서 이번 기록에는 Ktor는 무엇인지 어떻게 쓰는지 알아보려고 한다.
Ktor
Ktor: Build Asynchronous Servers and Clients in Kotlin
Kotlin Server and Client Framework for microservices, HTTP APIs, and RESTful services
ktor.io
Ktor는 JetBrains에서 만들었고, Kotlin과 Coroutine을 사용하여 구축되었다.
비동기 클라이언트 및 서버 응용프로그램을 만들 때 사용된다.
간단한 방법으로 마이크로 서비스에서 멀티플랫폼 HTTP 클라이언트 앱에 이르기까지 모든 것이 가능하다고 한다!
그리고 직관적인 명령적 흐름을 가진 비동기 프로그래밍의 힘 뿐만 아니라 간결한 다중 플랫폼 언어를 사용할 수 있다
그래서 Ktor는 오픈 소스이며 간단하고 재밌다!라고 소개해주고 있다!
알고 넘어가기!
- 코틀린(Kotliin)은 JVM에서 동작하는 크로스 플랫폼 오픈소스 프로그래밍 언어로 JetBranins에서 만들었다.
- 자바와 코틀린이 서로 호환이 되는 이유는 자바/코틀린 모두 Java bytecode로 컴파일 되기 때문
- 코틀린은 2019년 5월 7일 이후 구글의 안드로이드 앱 개발에서 선호하는 언어가 되었다.
- 구글은 2019년 Google I/O에서 코틀린 퍼스트를 선언하며
모든 문서에서 코틀린 코드를 먼저 노출하는 등 코틀린을 메인 언어로 지원하고 있다 - 코루틴은 Kotlin 버전 1.3에 추가되었으며 다른 언어에서 확립된 개념을 기반으로
비동기적으로 실행되는 코드를 간소화하기 위해 Android에서 사용할 수 있는 동시 실행 설계 패턴이다.
Ktor 간단하게 따라해보기
Create Ktor Applications
Kotlin Server and Client Framework for microservices, HTTP APIs, and RESTful services
ktor.io
IntelliJ IDEA에서 하거나 start.ktor.io를 통해 하거나 수동 구성을 하거나 선택해서 프로젝트를 시작할 수 있다
Ktor 프로젝트 생성하기
IntelliJ IDEA
https://ktor.io/docs/intellij-idea.html#create_ktor_project 를 참고해서 진행해보자!
이렇게 입력하고 Next를 누르니
Ktor 애플리케이션의 공통 기능을 제공하는 플러그인 세트를 선택할 수 있다.
예제에서는 들어오는 요청을 처리하기 위해 라우팅 플러그인만 설치한다고 되어 있어, Routing 검색 후 추가하겠습니다!
그러면 이렇게 프로젝트가 생성!
Ktor 애플리케이션 소스 확인해보기
그러면 프로젝트 경로에서 Application.kt파일과 Routing.kt 파일을 확인해보겠습니다
Application.kt
src/main/kotlin/com/.../Application.kt 파일을 열어줍니다
fun main() {
embeddedServer(Netty, port = 8080, host = "0.0.0.0") {
configureRouting()
}.start(wait = true)
}
공식 문서에서 이 코드의 주요 부분은 아래와 같다고 나와있습니다
- embeddedServer기능은 코드에서 서버 매개변수를 구성하고 애플리케이션을 빠르게 실행하는 간단한 방법입니다.
host:post에서 수신 대기하는 지정된 엔진으로 임베디드 서버를 생성한다고 되어 있습니다
즉, 위의 소스는 Netty 엔진으로 서버를 실행하고 0.0.0.0:8080 포트에서 수신과 대기를 합니다 - configureRouting은 Routing을 정의하는 확장 기능입니다.
이 함수는 별도의 plugins패키지( Routing.kt 파일)에 선언되어 있습니다.
Routing.kt
src/main/kotlin/com/.../plugins/Routing.kt파일을 열어줍니다
fun Application.configureRouting() {
routing {
get("/") {
call.respondText("Hello World!")
}
}
}
get함수는 "/" 경로에 대해 GET 요청을 수신하고 Hello World 텍스트로 응답하는 소스입니다.
알고 넘어가기
- Netty는 비동기 이벤트 기반 네트워크 애플리케이션 프레임워크입니다.
- EmbeddedServer는 HTTP 프로토콜을 구현하는 소프트웨어 시스템의 구성 요소이다
- 비동기 이벤트 기반 네트워크 애플리케이션 프레임워크와 도구들은
TCP, UDP 소켓 서버 등 네트워크 프로그래밍을 단순하게 만들기 위해 사용된다. - Netty는 유지관리 가능한 고성능 프로토콜 서버 및 클라이언트의 신속한 개발을 지원합니다.
Ktor 애플리케이션 실행해보기
src/main/kotlin/com/.../Application.kt 파일을 열어줍니다
그다음 main 함수 옆에 있는 아이콘을 클릭하고 ApplicationKt 실행을 선택합니다.
0.039seconds..?
실행이 되었다.
HTTP APIs
HTTP APIs 예제는 https://ktor.io/docs/creating-http-apis.html#source_code 이 링크를 통해 해 볼 수 있다.
위 링크를 통해 고객에 대한 CRUD 처리하는 방법을 간단하게 살펴보았다!
고객 모델 및 스토리지 생성
Customer.kt 파일 생성
@Serializable
data class Customer(val id: String, val firstName: String, val lastName: String, val email: String)
val customerStorage = mutableListOf<Customer>()
@Serializable로 API 응답에 필요한 JSON 표현으로 자동 생성할 수 있다
예제는 코드를 복잡하게 만들지 않기 위해 메모리 내 스토리지를 사용했다고 나와있습니다.
고객 라우팅
import io.ktor.http.*
import io.ktor.server.application.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
fun Route.customerRouting() {
route("/customer") {
get {
if (customerStorage.isNotEmpty()) {
call.respond(customerStorage)
} else {
call.respondText("No customers found", status = HttpStatusCode.OK)
}
}
get("{id?}") {
val id = call.parameters["id"] ?: return@get call.respondText(
"Missing id",
status = HttpStatusCode.BadRequest
)
val customer =
customerStorage.find { it.id == id } ?: return@get call.respondText(
"No customer with id $id",
status = HttpStatusCode.NotFound
)
call.respond(customer)
}
post {
val customer = call.receive<Customer>()
customerStorage.add(customer)
call.respondText("Customer stored correctly", status = HttpStatusCode.Created)
}
delete("{id?}") {
val id = call.parameters["id"] ?: return@delete call.respond(HttpStatusCode.BadRequest)
if (customerStorage.removeIf { it.id == id }) {
call.respondText("Customer removed correctly", status = HttpStatusCode.Accepted)
} else {
call.respondText("Not Found", status = HttpStatusCode.NotFound)
}
}
}
}
위 소스에 대해 간단하게 정리해보기!
- call.respond는 코틀린 객체를 가져와 지정된 형식으로 직렬 화하여 반환할 수 있는데
고객 모델 생성 시 @Serializable 어노테이션을 사용했기 때문에 JSON로 직렬화하여 반환한다 - call.parameters["id"]으로 지정한 매개 변수가 있는지 확인할 수 있다.
- call.receive는 구성된 Content Negotiation 플러그인과 통합된다.
- (customerStorage.removeIf { it.id == id }) 특정 고객 아이디가 있는지 여부
실제 사용 시에는 좀 더 복잡하게 이루어지겠지만 어떤 흐름인지 알 수 있다.
내가 생각해본 Ktor를 사용하면 생기는 이점은 무엇일까?
내가 정리하면서 든 생각은 소스도 간결하고 애플리케이션 실행 속도도 빠르기 때문에
개발 생산성이 높아지지 않을까 하는 생각이 먼저 들었다.
또한, 서비스가 커지고 있는 회사를 보면 대부분 하나의 큰 서비스를 작은 단위로 쪼개서 구현하는 MSA 아키텍처로 전환하고 있다.
그래서 간결한 코드로 개발할 수 있고 서버도 빠르게 구동할 수 있기에 확장이 용이하면서 신속하게 서비스를 배포해야 하는 MSA구조에 구현하면 이점이 있을 것이다.
하지만 국내/해외 채용 시장에는 Ktor를 사용하는 회사가 많지 않고
검색어 인기 분석에서도 Ktor는 적다.
실무에 어떤 문제점이 있어 Ktor를 쓰지 않은걸까?
아니면 나처럼 아예 있는 줄 몰랐던걸까?
분명 이유가 있겠지만 모래사장에서 바늘찾기처럼 알 수 없으니 더 궁금하긴 하다 ㅎㅎ
느낀 점
처음엔 진짜 놀랐다!!
코드가 진짜 정말 간결했다
코틀린이 탄생한 배경도 재미있었다.
젯브레인의 코드 70%는 Java로 작성되어 있었는데,
Java 말고 더 좋고 모던한 프로그래밍 언어로 바꾸고 싶어 했었다.
하지만 코드의 70%가 자바이기 때문에 쉽게 바꿀 수 없었을 것이다.
그런데!! 젯브레인은 자바와도 호환이 가능하고 새로운 언어로 바꾸는
두 마리 토끼를 잡으면서 코틀린이라는 언어를 만든 것이다.
니콜라스는 코틀린 장점을 Null safety / coroutine로 뽑았다고 했는데
코틀린은 변수 기본값이 null이 아닌 NotNull이다.
그래서 자바의 NullPointerException를 대응하고 나온 것이다.
coroutine은 go언어의 gorutine과 비슷하다고 한다.
coroutine은 간단하게 많은 걸 한 번에 실행하는 코드이기 때문에 다른 언어보다 빠르다.
이 이야기를 들으니 이래서 구글이 flutter 2.0 버전에서 Null Safety를 지원했구나!라는 혼자만의 생각을 하게 되었다
그렇게 생각한 이유는 구글이 2019년에 안드로이드 메인 언어를 자바에서 코틀린을 채택했고,
flutter 2.0 버전은 그 이후인 2021년 3월 4일에 나왔기 때문!
마지막으로 코틀린은 자바스크립트로 컴파일이 된다고 한다!!
그래서 코틀린으로 작성한 다음 JS로 컴파일해서 리액트나 노드로 가져가도 된다는 것 신기하다!!
[참고]
Ktor: Build Asynchronous Servers and Clients in Kotlin
Kotlin Server and Client Framework for microservices, HTTP APIs, and RESTful services
ktor.io
https://www.youtube.com/watch?v=8gseVzeMOzk
'IT > 기록' 카테고리의 다른 글
Flutter I/O Extended Korea 2022에 다녀오다! (0) | 2022.06.28 |
---|---|
[Flutter] 마스코트 귀여운 새! 이름은 무엇인가? (0) | 2022.06.27 |
[알고리즘] 검색 알고리즘 기초 개념 잡아가기 (0) | 2022.06.12 |
[Flutter] 프로젝트 패키지명 및 앱이름 변경하기 (0) | 2022.06.10 |
[Flutter] 첫 앱 게시 삽질기 #2 앱 상태 프로덕션 (0) | 2022.06.09 |