Ktor 作為一個輕量的框架,對框架效率的要求也是很常見的。
後端服務其中一個提升效能的方式,就是將回應進行壓縮,來減少網路傳輸的成本
Ktor 也提供壓縮的套件,讓我們簡單的壓縮回應
我們可以調整 build.gradle.kts 進行安裝
implementation("io.ktor:ktor-server-compression:$ktor_version")
安裝好之後,我們可以在 Application.module() 內加上 configureHTTP()
作為未來調整 HTTP 所有封包的結構
fun Application.module() {
    configureHTTP()
}
接著我們在 Application.configureHTTP() 內安裝壓縮的套件 Compression
fun Application.configureHTTP() {
    install(Compression)
}
這樣就安裝好了!不過要能看到壓縮的效果,我們還需要做一些調整
這邊預設的 encoder 有 gzip()、deflate()、identity(),不過我們可以在後面任意調整
install(Compression) {
    gzip()
}
由於 Ktor install() 的設計,我們不需要在這時候標記我們呼叫的是 CompressionConfig 的函數,Ktor 會知道這件事情。
如果我們想要調整個別 encoder 的優先序,也是可以的
install(Compression) {
    gzip {
        priority = 0.9
    }
    deflate {
        priority = 1.0
    }
}
Ktor 預設上會略過一些檔案不進行壓縮
excludeContentType(
    ContentType.Video.Any,
    ContentType.Image.JPEG,
    ContentType.Image.PNG,
    ContentType.Audio.Any,
    ContentType.MultiPart.Any,
    ContentType.Text.EventStream
)
我們可以用 matchContentType() 和 excludeContentType() 來調整我們要進行壓縮的檔案格式
比方說為了測試,原本我們的路由有
get("/") {
    call.respondText("Hello World!")
}
我們針對這個路由回傳的型態 ContentType.Text.Plain 進行 gzip 壓縮
install(Compression) {
    gzip()
    matchContentType(ContentType.Text.Plain)
}
設定好之後,我們如果用 curl 送出請求,並說明我們可以接受 gzip
就會看到壓縮後的內容
curl -i --compressed  http://0.0.0.0:8080
HTTP/1.1 200 OK
Content-Encoding: gzip
Vary: Accept-Encoding
Content-Type: text/plain; charset=UTF-8
transfer-encoding: chunked
Hello World!%
如果我們改成
install(Compression) {
    deflate()
    matchContentType(ContentType.Text.Plain)
}
那就會看到
curl -i --compressed  http://0.0.0.0:8080
HTTP/1.1 200 OK
Content-Encoding: deflate
Vary: Accept-Encoding
Content-Type: text/plain; charset=UTF-8
transfer-encoding: chunked
Hello World!%
除了根據類別進行區分哪些要壓縮哪些不壓縮,有時候我們可能會希望根據一些客製化條件進行區分
這時候我們可以用 condition() 進行設置
比方說如果路由 URI 是 test 起頭,那就不進行壓縮
首先我們加上 /test 路由,內容和 / 一樣
get("/") {
    call.respondText("Hello World!")
}
get("/test") {
    call.respondText("Hello World!")
}
然後調整壓縮的規則
install(Compression) {
    gzip()
    condition {
        !request.uri.startsWith("/test")
    }
    matchContentType(ContentType.Text.Plain)
}
這樣一來,如果我們試著打 http://0.0.0.0:8080/test 就不會壓縮了
curl -i --compressed http://0.0.0.0:8080/test
HTTP/1.1 200 OK
Content-Length: 12
Content-Type: text/plain; charset=UTF-8
Hello World!%
有關 Ktor 回應壓縮的部分,今天就說到這邊,我們明天見!