[Day 30] Ktor Q&A 与 Side Project Roadmap

终於来到铁人赛最後一天,本来想回顾总结我实作 side project 的过程,但想到读者应该对於 Ktor 仍有许多疑问而正在犹豫是否要采用它,所以我列出之前有人问我 Ktor 的问题,以我个人观点来回答这些疑问。

Ktor Q&A

目前 Ktor 成熟稳定吗? 有什麽大公司采用? 有实际案例吗?

Kotlin 是 JetBrains 所开发的程序语言,Ktor 也是由 JetBrains 开发的 100% Kotlin Web 框架,再加上 JetBrains 的重量级产品 Space 就是使用 Ktor 开发的,所以是足够成熟稳定的。许多人抱持着疑问是因为现在 Kotlin 大多应用在 Android 开发,比较少人拿来写 Server-Side,不过我认为未来会有更多後端新专案从 Java 转往 Kotlin,到时候 Kotlin 後端案例就会增多,自然使用 Ktor 的案例也会增加。

JetBrains 今年有投注更多人力资源於 Ktor 团队,而且 Kotlin 官方网站也把 Ktor 的位置放在网页最上方与 Spring 框架并列,最新举办的 Kotlin 2021 Premier Event 活动也有包含演讲主题 What's New in Ktor 2.0,这代表 JetBrains 是有认真在推广的。

Ktor 采用 Semantic Versioning,固定每个月的月底会发布新版本,Ktor 团队也承诺会尽量维持 API 稳定,大版本异动会保留时间让你升级再移除 API。根据今年 Ktor roadmap 及过往的 release note,我认为 Ktor 团队目前是想专心做好框架本身的功能,重构优化现有程序码,让开发者体验更好,而非整合很多第三方函式库来堆砌功能,所以以 Web 框架核心功能来说是愈趋稳定的。

Ktor 官方重大消息会发布在 Ktor Blog,这2年的 roadmap 可参考以下2篇文章

Ktor 只适合开发小专案或小型微服务吗?

以功能的角度来看,Ktor 本身并没有限制你只能开发多少或多大的功能,只是大专案通常需要比较多功能,然而现在 Ktor 很少已经整合好的框架函式库可以用而已。如果你不介意手刻或自行整合缺少的功能,那麽前期先花一些时间投资,後期的开发速度会大幅提升,我做这个 side project 的过程就是如此。

如果以效能的角度来看,Ktor 轻量启动速度快、记忆体花费少,再加上底层引击可以选择 Netty,所以我认为效能是可以与其它框架相提并论的。另外在应用程序开发层面也不必担心,Ktor 本身是基於 Coroutine 开发的,开发者自己也可使用 Coroutine 撰写简洁的非同步程序码。顺便一提,网路上搜寻 ktor performance benchmark 的文章,我建议要注意测试的框架版本及测试方式,避免受到过时的资讯误导 Is Ktor really that slow compared to other micro java frameworks?

使用 Ktor 框架开发的优缺点?

优点

  • 简洁易懂的 DSL 风格、大量使用 extension function 扩充功能、基於 Coroutine 函式库,充份发挥 Kotlin 语言的优点
  • 架构设计允许开发者很容易实作 Plugin 进行扩展及客制化
  • Unopinionated 的设计原则,开发者不受框架限制,可自由挑选想要整合的第三方框架函式库
  • 几行程序码就可以完成一个 API,可以快速开发一个小专案
  • 轻量而且核心很小、所以启动速度快,记忆体花费少,开发与测试的效率提高许多
  • JetBrains 是开发 IDE 软件的公司,所以很重视开发者体验及开发工具的整合。Ktor 团队今年推出了 Ktor Project Generator 及新版本 IntelliJ Ktor Plugin,虽然新版 Plugin 仅限 IntelliJ Ultimate 版本,不过 Ktor 本身仍然是 OpenSource 免付费的。

缺点

  • 需花时间自行整合第三方框架及函式库
  • 缺乏常用套件支援,例如 OpenAPI Generator, i18n
  • 官方文件仍有改进空间,有时需要自己 trace source code。不过最近几个月补文件的速度飞快,感觉有请人专门在写文件
  • 社群人数、网路教学文章、GitHub 专案范例都很少,只能依靠官方文件及主动发问解决问题。不过现在官方 Slack Channel 有团队成员进驻负责回答问题,不必害怕变孤儿求救无门。

Ktor 适合初学者吗? 一定要先学会 Java 吗?

如果你之前没有写程序的经验,而且学习目的是为了找工作,那我建议你学习 Spring Boot,因为工作机会非常多。 反之,如果你是对後端程序开发有兴趣,愿意花时间自学 Kotlin 及 Web 框架的话,我很推荐你选择 Ktor。这是因为 Ktor 是微框架,学习方式可以先专注学习 Web 框架本身的功能,後续再自己逐步整合第三方框架函式库,虽然学习过程会比较长,但会比较了解 Web 框架的运作机制。 而且 Ktor 运作机制不使用 annotation,都是使用函式呼叫,所以很容易透过 IDE 工具 trace 原始码,了解 Ktor 内部是如何运作的。

与 Ktor 相反,Spring Boot 已经整合好第三方框架函式库,初学者只要设定及撰写框架要求实作的程序码,就可以快速完成功能,容易获得成就感。但从另一个角度来看,初学者容易只专注於如何设定使用功能,而忽略了 Spring 框架背後的运作机制。此外,因为 Spring 已整合太多技术,市面上的书籍都很厚一本,初学者自学时容易分散注意力,觉得有很多东西要学而怯步,此时我建议要有老师带领,有计划地学习比较有效率。在此推荐 Vincent Huang 今年的铁人赛 Spring Framework X Kotlin 影片教学,初学者可以先对 Spring 各个面向有基本概念,之後再对有兴趣的主题深入学习,而且特别的是教学内容是使用 Kotlin 讲解。

至於学 Ktor 之前要不要先学 Java,我个人认为不需要,这是因为 Ktor 是 100% Kotlin 开发的,所有范例程序码也都是 Kotlin 写的,完全不需要撰写或阅读 Java 程序码。不过 Spring Boot 就建议你至少要能够阅读 Java 程序码,毕竟目前 Spring Boot 使用 Kotlin 开发的比例并不高,网路搜寻到的文章及解决方法大多是使用 Java 写的。

要如何学习 Ktor? 有那些学习资源?

第一步是先掌握 Kotlin 语法及特性,熟悉 Lambda & DSL 风格的程序码,再来学 Ktor。在这里推荐三本 Kotlin 书籍

目前网路上有关 Ktor 的文章很少,而且不够详细或已过时,建议直接看官方文件就好。要注意 Ktor 分为 server 端的 web 框架及 client 端的 http client library,我们要看的是 server 端部分。实作方面,可以使用 Project Generator 工具,勾选想要安装的 Plugin 即可产生专案,而且产生的程序码就是最好的学习范例。接下来就是根据你安装的 Plugin,搭配对应的说明文件进行实作,最後完成一个小专案。

因为 Ktor 使用人数很少,所以学习过程中容易有孤独感…XD,欢迎你加入 Kotlin 读书会,与同伴一起学习。这里除了有读书会活动之外,还有强调动手实作的练功场可以参加喔。

我是使用 Spring Boot 开发的 Java 後端工程师,新专案想改用 Kotlin 开发,有必要换框架吗? 例如 Ktor

如果你已习惯 Spring 框架的开发方式,那就完全不需要换框架,因为从 Spring 5 开始对 Kotlin 的支援度已经很好了。如果想知道如何使用 Kotlin 搭配 Spring 框架开发,我推荐可以看看 Vincent Huang 今年铁人赛 Spring Framework X Kotlin 的影片教学。

如果你跟我一样,想学习与 Java & Spring 不同风格的程序语言及框架 (虽然 Java 新版本一直加入现代新语言的特性…XD),但又不想跳太远离开 JVM 平台,那我觉得可以学一下 Kotlin & Ktor,让自己对於後端 Web 框架有另一种思维去解决同一个问题。

我想从非 Java/JVM 生态系转往 Kotlin,Ktor 适合我吗?

如果你喜欢 Ktor 的架构设计,或是原本就习惯 DSL 的开发风格,而且又不需要 Spring 完整的生态系,那麽可以先实作一个小专案玩玩看,再决定是否要继续使用 Ktor。

Side Project Roadmap

今年主要是学习 Kotlin 语言及研究使用 Ktor 开发的 Best Practice,并且已完成以下项目

  • 在 Multi-Project 架构下进行开发、建置、部署,减少未来从单体式架构迁移至微服务架构的工作
  • 实作 Ktor Plugin 整合第三方框架及函式库,包括 DI, ORM, Redis Client...等
  • 实作 Ktor 缺少的功能来强化 Ktor,包括 「i18n」, 「OpenAPI Generator」, 「API Role-Based Authorization」...等
  • 实作系统处理「Logging」及「Async Task」的机制
  • 实作後端常见的基本功能,包括「使用者登入验证」、「讯息通知」

预计接下来进行以下项目

  • Migrate to Ktor 2.0
    • 10月底马上就要发布 ktor 2.0 了,预期会有许多新功能及 API Breaking Change,所以需要花一些时间调整或改写。此外,Ktor 已经把 Feature 改名为 Plugin,这次顺便扫瞄所有程序码进行替换
  • 登入验证支援 OAuth
    • 目前只有实作密码验证,然而现在 OAuth 算是必备功能了
  • 讯息通知支援 LineNotify
    • 台湾用 Line 人数最多,而且 LineNotify 免费
  • 整合 RabbitMQ
    • Redis 与 Message Queue 是後端架构必备的二大利器,所以预计还会再整合 RabbitMQ,先应用在讯息通知功能上面
  • 整合 Exposed 与 R2DBC (目前已实验性整合成功)
    • 想使用 jasync-sql (R2DBC driver wrapper written in Kotlin) 非同步操作资料库。目前 jasync-sql 的 API 属於 low-level 操作,所以我想在上层利用 Exposed 的 Query DSL API 产生 sql,再传入下层的 jasync-sql 执行查询,jasync-sql 查询後再把结果转换回Exposed 的 ResultRow 物件,或是自定义的 DTO 物件。Query API 实作上是在 Exposed 的 Query, Table 类别加上许多 extension function,例如 Query.toFuture(): CompletableFuture<QueryResult> 所以开发时只要操作 Exposed API 就好,尽量隐藏 jasync-sql API 在下层
  • 部署至 GCP 或 Heroku
    • 现在我是部署至 AWS,有需要才启动,未来想搬家到比较便宜的 GCP 或 Heroku。不过在搬家之前,我要先把 AWS SES 及 Kinesis Data Firehose 的实作拔掉。

学习心得与感谢

这一年来从学习 Kotlin & Ktor 的基本知识开始,一路上不断地思考如何解决实作上遇到的问题,到现在完成了一个网站後端的系统雏形。 过程中我学习到

  • 如何拟定及调整 side project 的主题、范围及目标。题目太小太简单就学不到什麽,反而不想去做,但搞太大太复杂又会撑不下去而放弃,所以自己找到能长时间投入的方式是很重要的。例如卡关或累了那就休息一阵子,过一段时间回来,可能会想到新的问题或解决方式,就又有新的动力可以继续下去了
  • 透过学习使用不同的程序语言及 Web 框架开发,让我有不同的思维,以不同的方式去实作过去曾做过的功能
  • 透过手刻自干框架套件功能,学习到许多技术背後的实作细节,不再只是拿网路上的范例来修改使用而已
  • 对某个新技术进行深入学习,因为学习资源少,所以遇到问题要靠自己摸索解决,但是这样反而能逼迫自己去思考找出解决方法
  • 工作多年第一次参与社群,认识了许多学习伙伴,因为每个人的学习历程都不相同,所以可以扩展自己的知识广度

未来我希望能有更多人加入学习 Ktor 的行列,但我知道 Spring 框架生态系实在太强大,很难找到跟我一样是因为兴趣而学习 Ktor 的人,所以我认为推广 Ktor 最快最有效的方式就是动手实作一个具有一定规模的专案范例,证明 Ktor 是可以做到後端服务常见的功能,而且在 Github 还有开放原始码可以参考学习。不仅如此,我还希望这个范例不只是范例,是可以让别人在我改造後的 Ktor 框架上面进行开发,不必从原始的 Ktor 框架开始,缩短开发时间及帮大家先踩雷,这样才能提高采用 Ktor 的意愿。

最後我要感谢 Kotlin 爱台湾 2021 铁人赛团队的队友们,如果我没有参加团队,我可能无法坚持到最後完赛。还有要感谢各位读者,因为我很少写技术文章,而且内容包含许多实作细节,所以我也不确定大家是否都看得懂我在写什麽,如果有不清楚的地方,欢迎在下方留言发问。


<<:  [day23]加入购物车 & 库存检查

>>:  【DAY 21】为什麽每天可以有这麽多问题?如果有机器人可以帮帮我就好了!— Microsoft Power Virtual Agents 智慧虚拟助理来罗~

[Day2] 何谓 LHS、RHS 错误?

今天来了解 JavaScrip 的 LHS 错误、RHS 错误,两者皆与取值、赋值有关,首先先来了解...

#2-Installing Node JS

今天要来教大家如何安装 node.js 第一步:官网下载 左边的版本是稳定版,右边的版本是最新版,大...

[Day 28] 储存训练好的模型

储存训练好的模型 今日学习目标 使用 pickle + gzip 储存模型 将训练好的模型打包并储存...

【Day 28】设置开发环境 & 开发

tags: 铁人赛 蚵仔面线 萝卜丝饼 开发环境 env virtualenv 美食与废言 前阵子常...

[Day 13] 第一主餐 pt.6-叮咚,有您的包裹

上一篇我们把MySQL安装设定好,并且开始跟django做互动了 今天我们就要来把MySQL的东东全...