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 中发送具有相应内容类型的 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-Ranges HTTP 响应头部。 服务器使用此头部来声明其支持客户端对文件下载的局部请求。 在 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 请求体。 以下示例展示了一个带有 JSON 对象的 POST 请求体:

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 项目。

Multipart

在最后一节中,让我们看看如何处理 multipart 请求体。 下面的 POST 请求使用 multipart/form-data 类型发送一个带有描述的 PNG 图像:

http
Express

Express 需要一个单独的模块来解析 multipart 数据。 在下面的示例中, multer 用于将文件上传到服务器:

javascript

有关完整示例,请参阅 7_receive_request 项目。

Ktor

在 Ktor 中,如果您需要接收作为 multipart 请求一部分发送的文件, 请调用 receiveMultipart 函数,然后根据需要遍历每个部分。 在下面的示例中,PartData.FileItem 用于将文件作为字节流接收:

kotlin

有关完整示例,请参阅 7_receive_request 项目。

创建中间件

我们要看的最后一件事是如何创建中间件,它允许您扩展服务器功能。 以下示例展示了如何使用 Express 和 Ktor 实现请求日志记录。

Express

在 Express 中,中间件是使用 app.use 绑定到应用程序的函数:

javascript

有关完整示例,请参阅 8_middleware 项目。

Ktor

Ktor 允许您使用

自定义插件
了解如何创建自己的自定义插件。
扩展其功能。 以下代码示例展示了如何处理 onCall 以实现请求日志记录:

kotlin

有关完整示例,请参阅 8_middleware 项目。

后续内容

本指南中仍有许多未涵盖的用例, 例如会话管理、授权、数据库集成等。 对于大多数这些功能,Ktor 提供了专门的插件, 可以在应用程序中安装并根据需要进行配置。 要继续您的 Ktor 之旅, 请访问 学习页面 ,该页面提供了一系列分步指南和即用型示例。