Ktor練功場#2筆記-練習寫JSON API

YungHsin
10 min readAug 10, 2020

--

本次學習的實作重點:

(1) 重構原始碼

(2)製作FreeMarker網頁

(3)產生JSON API

(4)設定環境變數

重構原始碼

這次一開場就講了一些很實用的概念,就教怎麼在IntelliJ內將程式碼進行重構,這樣做的好處是讓你的程式碼易讀性變高,也能將不同功能的程式切割分類,也好進行重複使用。

重構前的程式碼長這樣:

get("/html-dsl") {
call.respondHtml {
body {
h1 { +"HTML" }
ul {
for (n in 1..10) {
li { +"$n" }
}
}
}
}
}

重構後的程式碼長這樣:

get("/html-dsl") {
htmlDsl()
}

這裡就來慢慢解說怎麼辦到的:

重構第一步:

將程式call.respondHtml這區塊的程式碼選取起來

重構第二步:

將程式區塊變成函式,只需按滑鼠右鍵->Refactor->Function

再自行取函式的名稱,例如:htmlDsl

這時程式雖然被獨立成一個函式,但依舊是被放在Application.kt內的,而我們希望不要把程式都擠在同一個檔案內,而是能依據功能來放在不同的檔案裡,往後有需要將比較好維護修改,也好進行測試。

重構第三步:

將函式移到新的檔案裡頭,一樣先選取程式碼,按滑鼠右鍵->Refactor->Move

出現Move的視窗後,勾選File name,檔案自動被取名為HtmlDsl.kt

按下Refactor後,檔案就會被移到src/HtmlDsl.kt底下了。

所以重構的程式碼不是不見了,而是放到其他地方,變成比較好看的樣子囉,功能上完全跟重構前會是一樣。

製作FreeMarker網頁

FreeMarker可能是常有接觸網頁設計的人比較常聽到吧,它就是一個Template Engine,而看官網的圖來說故事感覺是透過FreeMarker把Html跟Java程式整合,變成一個新的網頁樣版FTL(FreeMarker Template Language),所以FreeMarker的副檔名都叫.ftl。

圖片來源: https://freemarker.apache.org/

有興趣了解的人可以去官網翻翻資料:https://freemarker.apache.org/

這邊我就繼續寫怎麼透過IDE來產生一個FreeMarker的網頁

FreeMarker網頁建立第一步:

開新專案,一樣選擇用Ktor套件產生,Templating這裡勾選CSS DSL跟FreeMarker,而HttpClient Engine選Apache HttpCleint Engine,其餘步驟就是自行命名專案名稱,一直下一步就行了。

FreeMarker網頁建立第二步:

其實最基本的FreeMarker專案已經建立好了,可以去IDE右側按gradle大象application-> run 就能看到用FreeMarker產生的網頁。

將網址路徑多加html-freemarker就能看到1, 2, 3的結果。

FreeMarker網頁是怎麼弄出來的?

其實回頭看FreeMarker第一步建立專案,IDE就幫我們做了很多事

其一是幫我們在build.gradle檔案添加了freemarker套件

其二是幫我們在Application.kt加入程式運作需要的Configuration,

上頭寫的basePackagePath: templates意思就是會去載入在resources底下的ftl檔案

而index.ftl也是IDE幫我們產生出來的,這邊不多做語法的解釋(有興趣的自行研究囉),重點是有一個IndexData類型的變數值data,準備在<#list>…<#/list>內執行印出結果。

再回到Application.kt,看到主程式透過FreeMarkerContent,將index.ftl跟一個定義好的data class IndexData結合

mapOf裡頭的data就是在前面index.ftl檔案的變數data,而我們用語法to來將IndexData(list(1,2,3))傳入

mapOf("data" to IndexData(listOf(1, 2, 3)))

就看到最後的結果1,2,3在網頁顯示了!

產生JSON API

寫後端的其一重點就是設計API讓前端的人能串接使用,而一般常用的回傳格式都是使用JSON,所以這次練功也教我們怎麼很簡單地用Ktor來產生一個JSON API。

第一步老樣子也是要建立新專案,不過這次專案的設定你要在Server部分往下拉多一點,找到GSON勾選起來。

這個動作在專案建立後,自動幫忙在build.gradle加上gson的套件

也會在Application.kt加入程式運作需要使用到的ContenNegotiation,也就是gson本人,才能讓我們最後程式回傳內容顯示JSON格式。

接著程式自動產生範例,提供key: “hello” 跟value:“world”

最後老樣子,可以去IDE右側按gradle大象application-> run ,多輸入網址路徑/json/gson,就能看到JSON格式的結果了!! 寫一個簡單的JSON API就是這麼簡單!!

設定環境變數

這次練功也多教了我們這一招,就是怎麼在Ktor專案裡設定一些環境變數,有寫程式經驗的人,一定都常常被告誡說不要把一些敏感機密資訊直接寫到程式碼,這樣讓有心人士很容易透過程式碼反組譯等動作,就能輕易將你設定的資料輕易拿走了,所以將這些資料提出來到獨立的地方,會是較好的做法。

Ktor專案在產生專案時,就會有一個檔案在resources/application.conf,當然application.conf也會基本放一些專案所需的設定,例如發佈時對應的port跟這個application的module,若你有一些可能是專案在各處都需要存取到的設定,也能在此填寫設定。

這次的練習先想像我們之後要設計一個資料庫,然後需要帳號密碼才能進到資料庫存取資料,所以要把帳密試著寫到application.conf。

練習做環境設定步驟一:

輸入你想要的設定名稱跟數值,用剛剛的舉例就是資料庫存取需要的帳密,這裡就打個database{},裡頭需要的變數就是user跟password

database{
user = "yaya"
password = "Learn Ktor Together!"
}

在application.conf長這樣子

練習做環境設定步驟二:

設定好後,重點就是怎麼從程式裡頭進行提取的動作囉,你可以試著把練習程式先寫在Application.kt裡頭。

以下程式片段的意思就是從環境變數的配置裡的ktor.database.user跟ktor.database.password拿出字串

val user = environment.config.property("ktor.database.user").getString()
val password = environment.config.property("ktor.database.password").getString()

最後你能試著將把user跟password用System.out.println方式在Run的Console看結果

System.out.println("database user:${user} password:${password}")

登愣!最後你就看到你在application.conf設定的資料就拿出來囉!!

最後講者也有特別提醒,一般開發產品也不會直接把帳密這些機密資料直接寫在application.conf檔,通常先寫在這裡是為了開發階段測試用比較方便,也不會進版本控管裡(不然帳密大家都看光光?!),所以最終要發佈時這些資料都是交由公司的SRE跟DBA保管會是比較好的方式。

這次只是透過簡單的範例來講解這個環境變數功能,建議大家程式開發還是要盡量做到最低限度的保密措施,這樣才不會有一天被駭就欲哭無淚。

以上就是Ktor練功場#2的內容,講了很多實戰會用到的技巧,收穫很多!

歡迎各位也一起來練功場學習Ktor囉!

2020–07–26~2020–09–20相約在線上! 隔週一起來練功!

https://tw.kotlin.tips/dojos/ktortw

--

--

YungHsin
YungHsin

No responses yet