LaravelのmiddlewareでJsonResponseのデータを編集する


はじめに

LaravelでREST APIを作成する時、middlewareでRequestObjectに対し、何かしらのデータを編集するという例はかなり目にします。けれどもJsonResponseObjectに対してデータを編集するという例はあまり見かけないのです。かなりあるあるなケースだと思ったのに、あまり検索に引っかからないので書きました。
なお本記事で取り扱うLaravelのバージョンは8、phpのバージョンは7以上を想定しているのであしからず。

よくあるmiddlewareでRequestObjectのデータを編集するやつ

public function handle(Request $request, Closure $next)
{
    $input = $request->all();
    $result = $this->service->repository($input['some_input']);
    $request->merge(['result' => $result]);

    return $next($request);
}

なんかこういう感じで、入力に何かしらのデータが入っていたらDBに問合せて結果をRequestObjectに合流させる的な処理。
バリデーションでやるにはちょっと気持ち悪くて、コントローラで毎回やらせるのは面倒な感じのあれです。
多分LaravelでREST API書いてたら一度は使うと思います。

class Illuminate/Http/Response

何故かなかったmiddlewareでJsonResponseObjectのデータを編集するやつ

public function handle(Request $request, Closure $next)
{
    $input = $request->all();
    $result = $this->service->repository($input['some_input']);
    $request->merge(['result' => $result]);

    $response = $next($request);
    // Get the json_decoded data from the response.
    // mixed getData(bool $assoc = false, int $depth = 512)
    $response_data = $response->getData(true, 512);
    $response_data['result'] = $result;
    $response->setData($response_data);
    return $response;
}

Laravelのhandler内で$next()にRequestObjectを渡すと、コントローラでの処理が終わった後の任意のResponseObjectが返ってきます。
今回はREST APIとしての振る舞いControllerに期待するので、JsonResponseが返る事が期待されます。
そこで、Laravelのapiドキュメントを読みにいくと、丁度getDataとsetDataという素敵なメソッドを発見。
getDataはJsonResponseに入力されたデータをjson_dencodeして返してくれるメソッド。
setDatahはJsonResponseにデータを入れ直せるメソッド。
つまり、getDataで持ってきた配列に任意の処理をしてsetDataにそれを渡せば後付けでJsonResponseのデータの編集ができるというカラクリ。

class Illuminate/Http/JsonResponse

参考