Skip to content

Express から Ktor への移行

Express から Ktor への移行

このガイドでは、アプリケーションの生成や最初のアプリケーションの記述から、アプリケーションの機能を拡張するためのミドルウェアの作成まで、基本的なシナリオにおいて Express アプリケーションを Ktor へ移行する方法を見ていきます。

アプリの生成

Express

express-generator ツールを使用して、新しい Express アプリケーションを生成できます。

shell
Ktor

Ktor は、アプリケーションのスケルトンを生成するために以下の方法を提供しています。

詳細な手順については、

新しい Ktor プロジェクトの作成、オープン、実行
Ktor を使用してサーバーアプリケーションを開き、実行し、テストする方法を学びます。
のチュートリアルを参照してください。

Hello world

このセクションでは、GET リクエストを受け取り、定義済みのプレーンテキストで応答する、最もシンプルなサーバーアプリケーションを作成する方法を見ていきます。

Express

以下の例は、サーバーを起動し、ポート 3000 で接続を待機する Express アプリケーションを示しています。

javascript

完全な例については、1_hello プロジェクトを参照してください。

Ktor

Ktor では、コード内でサーバーパラメータを構成し、アプリケーションを素早く実行するために embeddedServer 関数を使用できます。

kotlin

完全な例については、1_hello プロジェクトを参照してください。

また、HOCON または YAML 形式を使用する外部構成ファイルでサーバー設定を指定することもできます。

上記の Express アプリケーションは、DateX-Powered-By、および ETag レスポンスヘッダーを追加することに注意してください。これらは次のように表示される場合があります。

Ktor で各レスポンスにデフォルトの Server および Date ヘッダーを追加するには、

DefaultHeaders
必要な依存関係: io.ktor:%artifact_name%
プラグインをインストールする必要があります。Etag レスポンスヘッダーを構成するには、
ConditionalHeaders
必要な依存関係: io.ktor:%artifact_name%
プラグインを使用できます。

静的コンテンツの配信

このセクションでは、Express と Ktor で画像、CSS ファイル、JavaScript ファイルなどの静的ファイルを配信する方法を見ていきます。 メインの index.html ページとリンクされたアセット一式が含まれる public フォルダーがあると仮定します。

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%

  • ETag および Last-Modified:

    ConditionalHeaders
    必要な依存関係: io.ktor:%artifact_name%

ルーティング

ルーティング
ルーティングは、サーバーアプリケーションでの着信リクエストを処理するためのコアプラグインです。
により、特定の HTTP リクエストメソッド (GETPOST など) とパスで定義された特定のエンドポイントに対して行われた着信リクエストを処理できます。 以下の例は、/ パスに対して行われた GET および POST リクエストを処理する方法を示しています。

Express
javascript

完全な例については、3_router プロジェクトを参照してください。

Ktor
kotlin

TIP

POSTPUT、または PATCH リクエストのリクエストボディを受信する方法については、リクエストの受信を参照してください。

完全な例については、3_router プロジェクトを参照してください。

次の例は、ルートハンドラーをパスごとにグループ化する方法を示しています。

Express

Express では、app.route() を使用して、ルートパスに対してチェーン可能なルートハンドラーを作成できます。

javascript

完全な例については、3_router プロジェクトを参照してください。

Ktor

Ktor は route 関数を提供しており、これによってパスを定義し、そのパスの HTTP メソッドをネストされた関数として配置します。

kotlin

完全な例については、3_router プロジェクトを参照してください。

どちらのフレームワークでも、関連するルートを単一のファイルにグループ化できます。

Express

Express は、マウント可能なルートハンドラーを作成するための express.Router クラスを提供しています。 アプリケーションのディレクトリに birds.js ルーターファイルがあると仮定します。 このルーターモジュールは、app.js に示すようにアプリケーションにロードできます。

javascript
javascript

完全な例については、3_router プロジェクトを参照してください。

Ktor

Ktor では、Routing 型の拡張関数を使用して実際のルートを定義するのが一般的なパターンです。 以下のサンプル (Birds.kt) は birdsRoutes 拡張関数を定義しています。 アプリケーション (Application.kt) の routing ブロック内でこの関数を呼び出すことで、対応するルートを含めることができます。

kotlin
kotlin

完全な例については、3_router プロジェクトを参照してください。

URL パスを文字列として指定する以外に、Ktor には

型安全なルート
Resources プラグインを使用すると、型安全なルーティングを実装できます。
を実装する機能が含まれています。

ルートパラメータとクエリパラメータ

このセクションでは、ルートパラメータとクエリパラメータへのアクセス方法について説明します。

ルート(またはパス)パラメータは、URL 内のその位置に指定された値をキャプチャするために使用される名前付きの URL セグメントです。

Express

Express でルートパラメータにアクセスするには、Request.params を使用できます。 たとえば、以下のコードスニペットの req.params["login"] は、/user/admin パスに対して admin を返します。

javascript

完全な例については、4_parameters プロジェクトを参照してください。

Ktor

Ktor では、ルートパラメータは {param} 構文を使用して定義されます。 ルートハンドラーでルートパラメータにアクセスするには、call.parameters を使用できます。

kotlin

完全な例については、4_parameters プロジェクトを参照してください。

以下の表は、クエリ文字列のパラメータにアクセスする方法を比較しています。

Express

Express でクエリパラメータにアクセスするには、Request.query を使用できます。 たとえば、以下のコードスニペットの req.query['price'] は、/products?price=asc パスに対して asc を返します。

javascript

完全な例については、4_parameters プロジェクトを参照してください。

Ktor

Ktor では、call.request.queryParameters を使用してクエリパラメータにアクセスできます。

kotlin

完全な例については、4_parameters プロジェクトを参照してください。

レスポンスの送信

前のセクションでは、プレーンテキストの内容で応答する方法をすでに見てきました。 JSON、ファイル、およびリダイレクトのレスポンスを送信する方法を見ていきましょう。

JSON

Express

Express で適切なコンテンツタイプで JSON レスポンスを送信するには、res.json 関数を呼び出します。

javascript

完全な例については、5_send_response プロジェクトを参照してください。

Ktor

Ktor では、

ContentNegotiation
ContentNegotiation プラグインは、クライアントとサーバー間のメディアタイプのネゴシエーションと、特定の形式でのコンテンツのシリアル化/非シリアル化の 2 つの主要な目的を果たします。
プラグインをインストールし、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 レスポンスヘッダーを追加します。 サーバーはこのヘッダーを使用して、クライアントからのファイルダウンロードの部分リクエスト(Partial requests)のサポートを通知します。 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 は、FreeMarker、Velocity など、いくつかの

JVM テンプレートエンジン
HTML/CSS または JVM テンプレートエンジンを使用して構築されたビューを操作する方法を学びます。
をサポートしています。 たとえば、アプリケーションリソースに配置された 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 プラグインは、クライアントとサーバー間のメディアタイプのネゴシエーションと、特定の形式でのコンテンツのシリアル化/非シリアル化の 2 つの主要な目的を果たします。
プラグインをインストールし、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 は、バイトシーケンスを非同期で読み書きするための ByteReadChannel および ByteWriteChannel を提供しています。

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 での開発を続けるには、一連のステップバイステップのガイドとすぐに使えるサンプルを提供している学習ページにアクセスしてください。