Skip to content

從 Express 遷移到 Ktor

在本指南中,我們將探討如何在基本情境下將 Express 應用程式遷移到 Ktor:從產生應用程式、編寫您的第一個應用程式,到建立中介軟體以擴展應用程式功能。

產生應用程式

Express

您可以使用 express-generator 工具產生一個新的 Express 應用程式:

shell
Ktor

Ktor 提供以下方式來產生應用程式骨架:

有關詳細說明,請參閱

建立、開啟及執行新的 Ktor 專案
了解如何使用 Ktor 開啟、執行及測試伺服器應用程式。
教學課程。

Hello world

在本節中,我們將探討如何建立最簡單的伺服器應用程式,該應用程式接受 GET 請求並以預定義的純文字回應。

Express

以下範例展示了 Express 應用程式,它啟動一個伺服器並在埠3000監聽連線。

javascript

有關完整範例,請參閱1_hello專案。

Ktor

在 Ktor 中,您可以使用embeddedServer函數在程式碼中配置伺服器參數並快速執行應用程式。

kotlin

有關完整範例,請參閱1_hello專案。

您也可以在採用 HOCON 或 YAML 格式的外部配置檔案中指定伺服器設定。

請注意,上述 Express 應用程式會新增DateX-Powered-ByETag回應標頭,其外觀可能如下所示:

若要在 Ktor 中將預設的ServerDate標頭新增到每個回應中,您需要安裝

DefaultHeaders
所需依賴項:io.ktor:%artifact_name% 原生伺服器支援:✅
插件。
ConditionalHeaders
所需依賴項:io.ktor:%artifact_name% 程式碼範例:%example_name% 原生伺服器支援:✅
插件可用於配置Etag回應標頭。

提供靜態內容

在本節中,我們將了解如何在 Express 和 Ktor 中提供靜態檔案,例如圖像、CSS 檔案和 JavaScript 檔案。假設我們有一個public資料夾,其中包含主要的index.html頁面和一組連結的資產。

Express

在 Express 中,將資料夾名稱傳遞給express.static函數。

javascript

有關完整範例,請參閱2_static專案。

Ktor

在 Ktor 中,使用staticFiles()函數將對/路徑的任何請求映射到public實體資料夾。此函數支援從public資料夾遞迴提供所有檔案。

kotlin

有關完整範例,請參閱2_static專案。

提供靜態內容時,Express 會新增一些回應標頭,其外觀可能如下所示:

若要在 Ktor 中管理這些標頭,您需要安裝以下插件:

  • Accept-Ranges :

    PartialContent
    所需依賴項:io.ktor:%artifact_name% 伺服器範例:download-file,客戶端範例:client-download-file-range 原生伺服器支援:✅

  • Cache-Control :

    CachingHeaders
    所需依賴項:io.ktor:%artifact_name% 程式碼範例:%example_name% 原生伺服器支援:✅

  • ETagLast-Modified :

    ConditionalHeaders
    所需依賴項:io.ktor:%artifact_name% 程式碼範例:%example_name% 原生伺服器支援:✅

路由

路由
路由是伺服器應用程式中處理傳入請求的核心插件。
允許處理對特定端點的傳入請求,該端點由特定的 HTTP 請求方法(例如 GETPOST 等)和路徑定義。以下範例展示了如何處理對/路徑的 GETPOST 請求。

Express
javascript

有關完整範例,請參閱3_router專案。

Ktor
kotlin

TIP

請參閱接收請求以了解如何接收 POSTPUTPATCH 請求的請求主體。

有關完整範例,請參閱3_router專案。

以下範例展示了如何按路徑分組路由處理器。

Express

在 Express 中,您可以使用 app.route() 為路由路徑建立可串聯的路由處理器。

javascript

有關完整範例,請參閱3_router專案。

Ktor

Ktor 提供了一個 route 函數,您可以透過它定義路徑,然後將該路徑的動詞作為巢狀函數放置。

kotlin

有關完整範例,請參閱3_router專案。

這兩個框架都允許您將相關路由分組到單一檔案中。

Express

Express 提供了 express.Router 類別來建立可掛載的路由處理器。假設我們的應用程式目錄中有一個birds.js路由檔案。這個路由模組可以按照app.js中的方式載入到應用程式中:

javascript
javascript

有關完整範例,請參閱3_router專案。

Ktor

在 Ktor 中,一種常見模式是使用 Routing 類型上的擴展函數來定義實際路由。以下範例(Birds.kt)定義了 birdsRoutes 擴展函數。您可以透過在 routing 區塊內呼叫此函數,在應用程式(Application.kt)中包含相應的路由:

kotlin
kotlin

有關完整範例,請參閱3_router專案。

除了將 URL 路徑指定為字串之外,Ktor 還包含了實作

型別安全路由
Resources 插件允許您實作型別安全的路由。
的功能。

路由和查詢參數

本節將向我們展示如何存取路由和查詢參數。

路由(或路徑)參數是一個命名的 URL 片段,用於捕獲其在 URL 中指定位置的值。

Express

若要存取 Express 中的路由參數,您可以使用 Request.params。例如,以下程式碼片段中的 req.parameters["login"] 將針對/user/admin路徑回傳admin

javascript

有關完整範例,請參閱4_parameters專案。

Ktor

在 Ktor 中,路由參數使用 {param} 語法定義。您可以使用 call.parameters 在路由處理器中存取路由參數:

kotlin

有關完整範例,請參閱4_parameters專案。

下表比較了如何存取查詢字串的參數。

Express

若要存取 Express 中的路由參數,您可以使用 Request.params。例如,以下程式碼片段中的 req.parameters["login"] 將針對/user/admin路徑回傳admin

javascript

有關完整範例,請參閱4_parameters專案。

Ktor

在 Ktor 中,路由參數使用 {param} 語法定義。您可以使用 call.parameters 在路由處理器中存取路由參數:

kotlin

有關完整範例,請參閱4_parameters專案。

傳送回應

在前面的章節中,我們已經了解如何以純文字內容回應。現在讓我們看看如何傳送 JSON、檔案和重新導向回應。

JSON

Express

若要在 Express 中傳送具有適當內容類型 (content type) 的 JSON 回應,請呼叫 res.json 函數:

javascript

有關完整範例,請參閱5_send_response專案。

Ktor

在 Ktor 中,您需要安裝

ContentNegotiation
ContentNegotiation 插件主要有兩個目的:協商客戶端和伺服器之間的媒體類型,以及以特定格式序列化/反序列化內容。
插件並配置 JSON 序列化器:

kotlin

若要將資料序列化為 JSON,您需要建立一個帶有 @Serializable 註解的資料類別:

kotlin

然後,您可以使用 call.respond 在回應中傳送此類別的物件:

kotlin

有關完整範例,請參閱5_send_response專案。

檔案

Express

若要在 Express 中回應一個檔案,請使用 res.sendFile

javascript

有關完整範例,請參閱5_send_response專案。

Ktor

Ktor 提供了 call.respondFile 函數,用於向客戶端傳送檔案:

kotlin

有關完整範例,請參閱5_send_response專案。

Express 應用程式在回應檔案時會新增Accept-RangesHTTP 回應標頭。伺服器使用此標頭來宣傳其支援客戶端對檔案下載的部分請求。在 Ktor 中,您需要安裝

PartialContent
所需依賴項:io.ktor:%artifact_name% 伺服器範例:download-file,客戶端範例:client-download-file-range 原生伺服器支援:✅
插件以支援部分請求。

檔案附件

Express

res.download 函數將指定檔案作為附件傳輸:

javascript

有關完整範例,請參閱5_send_response專案。

Ktor

在 Ktor 中,您需要手動配置Content-Disposition標頭,以將檔案作為附件傳輸:

kotlin

有關完整範例,請參閱5_send_response專案。

重新導向

Express

若要在 Express 中產生重新導向回應,請呼叫 redirect 函數:

javascript

有關完整範例,請參閱5_send_response專案。

Ktor

在 Ktor 中,使用 respondRedirect 傳送重新導向回應:

kotlin

有關完整範例,請參閱5_send_response專案。

範本

Express 和 Ktor 都支援使用範本引擎來處理視圖。

Express

假設我們在views資料夾中有以下 Pug 範本:

若要用此範本回應,請呼叫 res.render

javascript

有關完整範例,請參閱6_templates專案。

Ktor

Ktor 支援多種

JVM 範本引擎
了解如何使用 HTML/CSS 或 JVM 範本引擎建構視圖。
,例如 FreeMarker、Velocity 等。例如,如果您需要使用位於應用程式資源中的 FreeMarker 範本進行回應,請安裝並配置 FreeMarker 插件,然後使用 call.respond 傳送範本:

kotlin

有關完整範例,請參閱6_templates專案。

接收請求

本節將展示如何接收不同格式的請求主體。

原始文字

以下 POST 請求向伺服器傳送文字資料:

http

讓我們看看如何在伺服器端將此請求的主體作為純文字接收。

Express

若要在 Express 中解析傳入的請求主體,您需要新增 body-parser

javascript

post 處理器中,您需要傳遞文字解析器(bodyParser.text)。請求主體將在 req.body 屬性下可用:

javascript

有關完整範例,請參閱7_receive_request專案。

Ktor

在 Ktor 中,您可以使用 call.receiveText 將主體作為文字接收:

kotlin

有關完整範例,請參閱7_receive_request專案。

JSON

在本節中,我們將探討如何接收 JSON 主體。以下範例展示了一個 POST 請求,其主體中包含一個 JSON 物件:

http
Express

若要在 Express 中接收 JSON,請使用 bodyParser.json

javascript

有關完整範例,請參閱7_receive_request專案。

Ktor

在 Ktor 中,您需要安裝

ContentNegotiation
ContentNegotiation 插件主要有兩個目的:協商客戶端和伺服器之間的媒體類型,以及以特定格式序列化/反序列化內容。
插件 並配置 Json 序列化器:

kotlin

若要將接收到的資料反序列化為物件,您需要建立一個資料類別:

kotlin

然後,使用接受此資料類別作為參數的 receive 方法:

kotlin

有關完整範例,請參閱7_receive_request專案。

URL 編碼

現在讓我們看看如何接收使用application/x-www-form-urlencoded類型傳送的表單資料。以下程式碼片段展示了一個包含表單資料的 POST 請求範例:

http
Express

與純文字和 JSON 一樣,Express 需要 body-parser。您需要將解析器類型設定為 bodyParser.urlencoded

javascript

有關完整範例,請參閱7_receive_request專案。

Ktor

在 Ktor 中,使用 call.receiveParameters 函數:

kotlin

有關完整範例,請參閱7_receive_request專案。

原始資料

下一個用例是處理二進位資料。以下請求將帶有application/octet-stream類型的 PNG 圖像傳送到伺服器:

http
Express

若要在 Express 中處理二進位資料,請將解析器類型設定為 raw

javascript

有關完整範例,請參閱7_receive_request專案。

Ktor

Ktor 提供了 ByteReadChannelByteWriteChannel,用於非同步讀取/寫入位元組序列:

kotlin

有關完整範例,請參閱7_receive_request專案。

多部分

在最後一節中,讓我們看看如何處理多部分主體。以下 POST 請求使用multipart/form-data類型傳送帶有描述的 PNG 圖像:

http
Express

Express 需要一個單獨的模組來解析多部分資料。在以下範例中,multer用於將檔案上傳到伺服器:

javascript

有關完整範例,請參閱7_receive_request專案。

Ktor

在 Ktor 中,如果您需要接收作為多部分請求一部分傳送的檔案,請呼叫 receiveMultipart 函數,然後根據需要迴圈遍歷每個部分。在以下範例中,使用 PartData.FileItem 將檔案作為位元組流接收:

kotlin

有關完整範例,請參閱7_receive_request專案。

建立中介軟體

我們將探討的最後一件事是如何建立中介軟體,它允許您擴展伺服器功能。以下範例展示了如何使用 Express 和 Ktor 實作請求日誌記錄。

Express

在 Express 中,中介軟體是使用 app.use 繫結到應用程式的函數:

javascript

有關完整範例,請參閱8_middleware專案。

Ktor

Ktor 允許您使用

自訂插件
了解如何建立您自己的自訂插件。
擴展其功能。以下程式碼範例展示了如何處理 onCall 以實作請求日誌記錄:

kotlin

有關完整範例,請參閱8_middleware專案。

下一步

本指南中仍有許多未涵蓋的用例,例如會話管理、授權、資料庫整合等等。對於其中大多數功能,Ktor 提供了專用插件,這些插件可以安裝在應用程式中並根據需要進行配置。要繼續您的 Ktor 之旅,請訪問學習頁面,其中提供了一系列逐步指南和可立即使用的範例。