0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SOCKET-MANAGERを使ったREST-APIサーバー開発の手引き<イベントハンドラ型実装>

0
Posted at

はじめに

このページでは、REST-API サーバー開発環境における イベントハンドラ型の実装方法 について解説します。
イベントハンドラ型は、受信したリクエストに対して 単一の処理(UNIT)を即時実行する 方式で、シンプルな API や軽量な処理に適しています。

イベントハンドラ型のイベント処理クラスはスキャフォールディングで自動生成できます。

なお、生成されたイベント処理クラスは メイン処理クラスの $classes['event'] にクラス名を設定することで適用されます
また、ルーティング定義の event キーには イベント処理クラス内のメソッド名 を指定します。

UNIT の基本概念については、以下のページで詳しく解説しています。

イベントハンドラ型の役割

イベントハンドラ型のイベント処理クラスは、REST-API の処理において以下のような役割を持ちます。

  • 単一の処理(UNIT)を即時実行する
  • 軽量な API や単発レスポンスに適している
  • ステートマシン型よりもシンプルで実装コストが低い
  • ルーティングの event キーに対応するメソッドが直接呼び出される

スキャフォールディング(生成方法)

イベントハンドラ型のイベント処理クラスは以下のコマンドで生成できます。

イベントハンドラ型生成コマンド
php worker custom:event-handler <カスタム名>

生成されるファイル例:

生成ファイル例
app/EventClass/<カスタム名>.php

生成されたクラスは メイン処理クラスの $classes['event'] にクラス名を設定することで適用されます
ルーティング定義の event キーには、イベント処理クラス内の メソッド名 を指定します。

カスタムコマンドの仕組みについては以下をご覧ください。

生成されるクラスの構造

スキャフォールディングで生成されるイベントハンドラクラスは以下のような構造になります。

イベントハンドラ生成クラス例
<?php

namespace App\EventClass;

use App\CommandUnits\CommandForHandler;

class <カスタム名> extends CommandForHandler
{
    protected function responseJson($p_param)
    {
        $p_param->response()->json(['message' => 'Hello API']);
    }
}

● 特記事項

  • コマンドで指定した カスタム名 がクラス名になる
  • 生成先は app/EventClass 配下
  • CommandForHandler を継承することでイベントハンドラ型として認識される
  • メイン処理クラスの $classes['event'] にクラス名を設定する
  • ルーティングの event キーには メソッド名 を設定する

レスポンス操作の基本

● ステータスコードの設定

statusメソッド例
$p_param->response()->status(404, 'Not Found');

理由句は省略可能で、指定しない場合は自動で 200 OK になります。

● ヘッダの設定

headerメソッド例
$p_param->response()->header('X-Sample', 'value');

● 単発レスポンス

textレスポンス例
$p_param->response()->text('Hello');
jsonレスポンス例
$p_param->response()->json(['message' => 'OK']);
fileレスポンス例
$p_param->response()->file('./path/file.txt');
downloadレスポンス例
$p_param->response()->download('./path/file.txt');

チャンク転送・SSE の利用について

イベントハンドラ型実装では、以下のように チャンク転送(Chunked Transfer)SSE(Server-Sent Events) を簡単に利用できます。

● チャンク転送の例

イベントハンドラ型でのチャンク転送例
$p_param->response()->chunked("1行目のデータです\n");
$p_param->response()->chunked("2行目:少しずつ送信しています...\n");
$p_param->response()->chunked("3行目:もう少しお待ちください...\n");
$p_param->response()->chunked("4行目:最後のデータです\n");
$p_param->response()->end();

● SSE の例

イベントハンドラ型でのSSE例
$p_param->response()->event("1回目のデータです", p_id: "sse0");
$p_param->response()->event("2回目:少しずつ送信しています...", p_id: "sse1");
$p_param->response()->event("3回目:まだ続きます...", p_id: "sse2");
$p_param->response()->event("done", p_event: "end");
$p_param->response()->end();

上記のように、イベントハンドラ型でもストリーミングレスポンスを簡潔に記述できますが、イベントハンドラ型は 1 回のメソッド実行内でレスポンスをまとめて処理する方式 のため、以下のようなケースが発生する可能性があります。

  • 送信したデータがネットワーク層で部分的に結合されて届く
  • 複数回に分けたつもりのデータが、クライアント側で一度に受信される
  • 確実な分割送信(逐次ステップ実行)が保証されない

そのため、確実に段階的な送信を行いたい場合 や、ステップごとに非同期処理・待機処理(setTimeout など)を挟みたい場合 は、ステートマシン型(ステートマシン型) の利用を推奨します。

ステートマシン型では、UNIT ごとにステータスを分けて処理を実行するため、確実な分割送信・逐次処理・非同期遷移 が保証されます。
チャンク転送や SSE を厳密に制御したい場合は、ステートマシン型を選択してください。

Range送信の実装例

Range送信では、バイナリデータやファイルデータの 全量をそのまま渡すだけで 、フレームワーク側が Range ヘッダの有無を自動判定し、必要な範囲の切り貼りを行ってレスポンスを返します。
デベロッパーは Range 処理を意識する必要がなく、通常のレスポンスと同じ感覚で扱えます。

● rangeBinary

rangeBinary例
$p_param->response()->rangeBinary($binary_data);

バイナリデータの全量を渡すだけで、Range 指定があればフレームワークが自動で切り出して返します。

● rangeFile

rangeFile例
$p_param->response()->rangeFile('./path/file.txt');

ファイルパスを渡すだけで、Range 指定に応じた部分送信をフレームワークが自動処理します。

おわりに

イベントハンドラ型は、REST-API サーバー開発において 軽量な処理・単発レスポンス を実装する際に最適な方式です。
スキャフォールディングを活用することで、イベント処理クラスの作成を効率化できます。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?