fontcolor_theme
Deepkit HTTP

イベント

HTTP モジュールはワークフローエンジンに基づいており、HTTP リクエストの処理全体のプロセスにフックするために使用できる様々なイベントトークンを提供します。

ワークフローエンジンは有限状態機械であり、各 HTTP リクエストごとに新しい状態機械インスタンスを作成し、位置から位置へとジャンプします。最初の位置は start、最後は response です。各位置で追加のコードを実行できます。

各イベントトークンには、追加情報を含む独自のイベントタイプがあります。

httpWorkflow.onRequest新しいリクエストが入ってきたとき
httpWorkflow.onRouteリクエストからルートを解決する必要があるとき
httpWorkflow.onRouteNotFoundルートが見つからなかったとき
httpWorkflow.onAuth認証が行われるとき
httpWorkflow.onResolveParametersルートのパラメータが解決されるとき
httpWorkflow.onAccessDeniedアクセスが拒否されたとき
httpWorkflow.onControllerコントローラーのアクションが呼び出されたとき
httpWorkflow.onControllerErrorコントローラーのアクションがエラーをスローしたとき
httpWorkflow.onParametersFailedルートのパラメータの解決に失敗したとき
httpWorkflow.onResponseコントローラーのアクションが呼び出されたとき。ここで結果をレスポンスへ変換します。

すべての HTTP イベントはワークフローエンジンに基づいているため、指定されたイベントを利用し、event.next() メソッドでそこへジャンプすることで、その挙動を変更できます。

HTTP モジュールは、これらのイベントトークンに対して独自のイベントリスナーを使用して HTTP リクエスト処理を実装しています。これらのイベントリスナーはすべて優先度が 100 に設定されており、あなたがイベントをリッスンするとデフォルトでは(デフォルトの優先度は 0 のため)あなたのリスナーが先に実行されます。HTTP のデフォルトハンドラーの後に実行したい場合は、優先度を 100 より大きく設定してください。

例えば、コントローラーが呼び出されたときのイベントを捕捉したいとします。特定のコントローラーが呼び出される場合、ユーザーがそれにアクセスできるかを確認します。ユーザーにアクセス権があればそのまま続行します。そうでなければ、次のワークフロー項目 accessDenied にジャンプします。そこでは、アクセス拒否の処理が自動的に継続されます。

import { App } from '@deepkit/app';
import { FrameworkModule } from '@deepkit/framework';
import { HtmlResponse, http, httpAction, httpWorkflow } from '@deepkit/http';
import { eventDispatcher } from '@deepkit/event';

class MyWebsite {
    @http.GET('/')
    open() {
        return 'Welcome';
    }

    @http.GET('/admin').group('secret')
    secret() {
        return 'Welcome to the dark side';
    }
}

const app = new App({
    controllers: [MyWebsite],
    imports: [new FrameworkModule]
})

app.listen(httpWorkflow.onController, async (event) => {
    if (event.route.groups.includes('secret')) {
        //ここで Cookie セッション、JWT などの認証情報を確認します。

        //これは 'accessDenied' ワークフロー状態にジャンプし、
        //実質的にすべての onAccessDenied リスナーを実行します。

        //私たちのリスナーは HTTP カーネルのものより先に呼び出されるため、
        //標準のコントローラーアクションは決して呼び出されません。
        //これは内部的に event.next('accessDenied', ...) を呼び出します
        event.accessDenied();
    }
});

/**
 * 既定の accessDenied 実装を変更します。
 */
app.listen(httpWorkflow.onAccessDenied, async () => {
    if (event.sent) return;
    if (event.hasNext()) return;
    event.send(new HtmlResponse('No access to this area.', 403));
})

app.run();
$ curl http://localhost:8080/
Welcome
$ curl http://localhost:8080/admin
No access to this area
English中文 (Chinese)한국어 (Korean)日本語 (Japanese)Deutsch (German)