PHPとJavaScriptで扱うオブジェクトのキー名がスネーク、キャメルと異なる場合に
サーバサイドで変換するミドルウェアを作成したのでそれを紹介します。
背景
フロントサイドとサーバサイドを両方まとめて実装することがよくある。
そのときにフロントから送るリクエストボディのキー名がキャメルケースで、サーバサイドでそれをスネーク型に変換したりする。
それをコントローラのロジック内でわちゃわちゃするのは、個人的には好きではなく。
コントローラ外で共通化できるようなことをしたいなぁと思い、ミドルウェアでそれを実現することにしました。
前提
- Laravelのミドルウェアについてある程度わかる
実装
ミドルウェアを作って、それを適用するだけ
ミドルウェア(CaseConverterMiddleware)を作成
app/Http/Middleware/CaseConverterMiddleware.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
<?php namespace App\Http\Middleware; use Illuminate\Support\Str; use Closure; class CaseConverterMiddleware { /** * 送信されてきたリクエストの処理 * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { $form_input = $request->input(); $request->replace($this->_recursiveConvert((array) $form_input, 'snake')); $response = $next($request); $response_content = json_decode($response->getContent(), true); $converted_response_content_json = json_encode($this->_recursiveConvert($response_content, 'camel')); $response->setContent($converted_response_content_json); return $response; } private function _recursiveConvert(array $items, string $method) { $new_items = []; foreach ($items as $key => $value) { $new_key = Str::{$method}($key); if (!is_array($value)) { $new_items[$new_key] = $value; } else { $new_items[$new_key] = $this->_recursiveConvert($value, $method); } } return $new_items; } } |
_recursiceConvert
で受けとった配列のキーをスネーク<=>キャメル
変換をしています。
値が配列になっている場合もあるので、再起的に実行するようにしています。
app/Http/Kernel.phpにミドルウェアを登録
全てのAPIで適用したい場合は、$middleware
の中に
特定のAPIのグループに対して適用したい場合は、$middlewareGroups
の中に記述します。
今回は、特にグループを意識していないので$middleware
の中に入れます。
app/Http/Kernel.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
<?php namespace App\Http; use Illuminate\Foundation\Http\Kernel as HttpKernel; class Kernel extends HttpKernel { /** * The application's global HTTP middleware stack. * * These middleware are run during every request to your application. * * @var array */ protected $middleware = [ \App\Http\Middleware\TrustProxies::class, \App\Http\Middleware\CheckForMaintenanceMode::class, \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, \App\Http\Middleware\TrimStrings::class, \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, \App\Http\Middleware\CaseConverterMiddleware::class, # <= これ ]; . . . |
これで実装は完了です。
まとめ
- フロントとサーバで渡すデータのキーの型が異なる要件は起こりうる
- サーバでそれをうまく変換する場合はミドルウェアを通すと良い