포디 Podi
또렷한 기억보다 글이 낫다
포디 Podi
  • 분류 전체보기 (83)
    • 책 (14)
      • 기록 (14)
      • 한줄 (0)
    • IT (62)
      • 기록 (61)
    • 일상 (5)
      • 음식 (0)
      • 기록 (5)
    • 게임 (0)
      • 몬스터헌터 (0)

블로그 메뉴

  • 홈으로
  • 방명록
  • 태그들
  • 깃허브
  • 유튜브
  • 인스타

공지사항

인기 글

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
포디 Podi

또렷한 기억보다 글이 낫다

[Ktor] Ktor는 뭘까?
IT/기록

[Ktor] Ktor는 뭘까?

2022. 6. 13. 18:25
728x90

채용 공고 지원 자격에 Ktor가 있었다!

처음 보자마자 뭘까??? 하고 궁금하게 되었다.

그래서 이번 기록에는 Ktor는 무엇인지 어떻게 쓰는지 알아보려고 한다.

 

Ktor 

https://ktor.io/

 

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 간단하게 따라해보기

https://ktor.io/create/

 

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  를 참고해서 진행해보자! 

Getting started with a Ktor Server

이렇게 입력하고 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로 컴파일해서 리액트나 노드로 가져가도 된다는 것 신기하다!!

 

 

 

 

[참고]

https://ktor.io/

 

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
    'IT/기록' 카테고리의 다른 글
    • Flutter I/O Extended Korea 2022에 다녀오다!
    • [Flutter] 마스코트 귀여운 새! 이름은 무엇인가?
    • [알고리즘] 검색 알고리즘 기초 개념 잡아가기
    • [Flutter] 프로젝트 패키지명 및 앱이름 변경하기
    포디 Podi
    포디 Podi
    기록은 복리다

    티스토리툴바