Благодаря ответу AnsellC я решил его с помощью макросов ответа (https://laravel.com/docs/5.8/responses#response-macros). Мое решение выглядит следующим образом:
<?php
namespace App\Providers;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Response;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Str;
class ApiResponseMacroServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* @return void
*/
public function boot()
{
Arr::macro('renameKeysCamel', function($array){
$newArray = array();
foreach($array as $key => $value) {
if(is_string($key)) $key = Str::camel($key);
if(is_array($value)) $value = static::renameKeysCamel($value);
$newArray[$key] = $value;
}
return $newArray;
});
// API Response macros
Response::macro('success', function ($data, $message = '') {
// If collection change it to associative array
if($data instanceof Arrayable) $data = $data->toArray();
if(is_object($data)) $data = (array) $data;
// Change to camelCase key names
if(is_array($data)) $data = Arr::renameKeysCamel($data);
return Response::json([
'success' => true,
'message' => $message,
'data' => $data,
]);
});
Response::macro('error', function ($message, $error_code = null, $status = 400) {
return Response::json([
'success' => false,
'errorCode' => $error_code,
'message' => $message,
], $status);
});
}
}
Он регистрирует два макроса для ответов REST API: success($data, $message)
и error($message, $error_code, $status)
. Существует третий макрос, расширяющий Illuminate\Support\Arr
для рекурсивного изменения ключей на camelCase renameKeysCamel
.
В качестве завершения здесь приведен код для обработки входящего запроса промежуточным программным обеспечением и изменения ключей JSONto snake_case:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Str;
class ProcessIncomingJsonMiddleware
{
/**
* Handle an incoming request and change json data keys to snake_case.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
if ($request->isJson())
{
// Fetch json data
$json_array = $this->renameKeysSnake($request->json()->all());
// Create changed response
$request->json()->replace($json_array);
}
return $next($request);
}
protected function renameKeysSnake($array) {
$newArray = array();
foreach($array as $key => $value) {
if(is_string($key)) $key = Str::snake($key);
if(is_array($value)) $value = $this->renameKeysSnake($value);
$newArray[$key] = $value;
}
return $newArray;
}
}