根據 2020/8/23-2020/11/15 練功場的筆記所做的自己的學習筆記。
~ 2021/3/23
結論
照著筆記做了一次 Ktor 範例,覺得 Ktor 真的是滿輕便的。
今年的練功坊如果還有 Ktor,希望可以跟著做點什麼。
1.Hello
學到
Hello
參考
- Ktor練功場#1筆記-就是在說哈囉我的 - YungHsin
用 community 版 - [Day 3] Ktor 的 Hello World-Recca
用 Ultimate 版 - Day 3:資料管理伺服器 (1) – 使用 Ktor 建立 HTTP Server
程式的進入點:Application.kt
執行:Gradle>Tasks>spplication>run
我的http://0.0.0.0:8080 沒有連上,要用 127.0.0.1
2.Response
學到
- Response
- html template engine
- json response
- routing
參考
- Ktor 練功場筆記(2)-重構、Template、Content Negotiation - Andy Lu
- Ktor練功場#2筆記-練習寫JSON API - YungHsin
- [Day 12] 要準備連線資料了!設置 Ktor 的連線資訊
- 重構程式
- 利用 Template Engine 回傳一個網頁
- 利用 Content Negotiation 回傳JSON格式的資料 (JSON API)
- 設定環境變數
routing
routing {
get("/") {
call.respondText("HELLO WORLD!", contentType = ContentType.Text.Plain)
}
}
Templates Engines(樣板引擎)
Ktor支援的Templates Engines表,如下:
- Freemarker
- HTML DSL
- Mustache
- Pebble
- Thymeleaf
- Velocity
DSL
get("/html-dsl") {
call.respondHtml {
body {
h1 { +"HTML" }
ul {
for (n in 1..10) {
li { +"$n" }
}
}
}
}
}
Freemarker
get("/html-freemarker") {
call.respond(FreeMarkerContent("index.ftl", mapOf("data" to IndexData(listOf(1, 2, 3))), ""))
}
Content negotiation (內容協商)
使用 Content Negotiation 可以讓資料轉成其它格式,如 Json。
Ktor支援的 Content negotiation 表,如下:
- Gson
- Jackson
- kotlinx.serialization
Refactor
使用快速鍵抽取程式碼 (Extract Function)
(Windows): Ctrl + W
(Windows): Ctrl+Alt+M
config
將機密資料寫在config,再import
設定好用這個 route 測試,變數成功從 config property引入
get("/password") {
val password = environment.config.property("ktor.database.password").getString()
call.respondText(password, contentType = ContentType.Text.Plain)
}
3.DB Expose & H2
學到
- Expose,H2
- DAO
- config
- H2 console
參考
- Ktor 練功場筆記(3) — 資料庫串接
- Ktor練功場#3筆記-使用Exposed資料庫
- [Day 13] 用 Ktor 連線資料庫!談 Kotlin exposed 框架
- [Day 15] 遠征 Kotlin × Spring Boot 設定資料庫與匯入初始資料
Exposed
在 Exposed 中,可以使用兩種方式存取資料庫:
- 包裝在 DSL (Domain Specific Language — 領域特定語言) 中,具有型別安全的 SQL 指令
- 輕量的DAO (Data Access Object — 資料存取物件)
目前支援的資料庫如下:
- H2
- MySQL
- MariaDB
- Oracle
- PostgreSQL
- PostgreSQL using the pgjdbc-ng JDBC driver
- SQL Server
- SQLite
我們在 gradle.build 裡面加上 h2database和exposed
旁邊的大象叫你更新
資料庫串接
以 Andy 的筆記做
https://github.com/andyludeveloper/ktor_workshop/blob/master/src/Application.kt
這邊被自動 impor 搞了一下,他幫我 import 到 connect,害我跟這範例卻出錯
import org.jetbrains.exposed.sql.Database.Companion.connect
import 到 Database 這一層就能跟範例一樣用Database.connect
import org.jetbrains.exposed.sql.Database
4.Request
- Ktor練功場#4筆記-使用Client串接第三方API
- https://ktor.io/docs/requests.html
- https://ktor.io/docs/getting-started-ktor-client.html#create-kotlin-file
andy 棄坑QQ
要有Json serialization for HttpClient
implementation "io.ktor:ktor-client-core:$ktor_version"
出現這個錯誤
確定有安裝 ktor client,後來看官方文件發現是要 import request
import io.ktor.client.request.*
完成
get("/") {
//用泛型
//val htmlContent = client.get<String>("https://en.wikipedia.org/wiki/Main_Page")
//call.respondText(htmlContent, contentType = ContentType.Text.Plain)
//也可以用宣告
val content: String = client.get("https://en.wikipedia.org/wiki/Main_Page")
call.respondText(content, contentType = ContentType.Text.Plain)
}
5.Asynchronous
- Ktor練功場#5筆記-非同步處理
- https://ktor.io/docs/request.html#concurrency
routing {
//mock server
get("/json/jackson1") {
delay(2000)
call.respond(mapOf("hello" to "hello1"))
}
get("/json/jackson2") {
delay(2000)
call.respond(mapOf("hello" to "hello2"))
}
get("/json/jackson3") {
delay(2000)
call.respond(mapOf("hello" to "hello3"))
}
//client
get("/"){
val beginTime = System.currentTimeMillis()
val msg1 = client.get<String>("http://localhost:8080/json/jackson1")
val msg2 = client.get<String>("http://localhost:8080/json/jackson2")
val msg3 = client.get<String>("http://localhost:8080/json/jackson3")
val resultMsg = "${msg1}${msg2}${msg3}"
val endTime = System.currentTimeMillis()
call.respondText("${resultMsg}\n costTime(millionseconds):${endTime-beginTime}")
}
}
執行要六秒
async
//import
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
//加上 async tag
val msg1 = async {client.get<String>("http://localhost:8080/json/jackson1")}
變快了
await
//val resultMsg = "${msg1}${msg2}${msg3}"
val resultMsg = "${msg1.await()}${msg2.await()}${msg3.await()}"
非同步
6.Deploy
兩種方法自己選
- Ktor練功場#6筆記-Fat Jar部署
- 我在 kotlin讀書會的日子(八):Ktor組聚 - Heroku雲端佈署
7.FP & OOP (SOLID, DP)
沒部落格看 QQ