php - Laravel middleware to format keys of response array

Solution:
If you are looking into formatting the OUTPUT of your app, the best way is to use Macros: https://laravel.com/docs/5.8/responses#response-macros or Response resources https://laravel.com/docs/5.8/eloquent-resources#resource-responses
From the docs: Middlewares provide a convenient mechanism for filtering HTTP requests entering your application.
But if you really wanna do it using middleware:
public function handle($request, Closure $next)
{
$response = $next($request);
foreach($response->getOriginalContent()->getData() AS $key => $value) {
//handle replacing of response here
}
...
}
I don't quite understand what you mean by "Handle an outgoing response." on your docbloc but if you're looking into filtering the incoming JSON POST request try the method below.
public function handle($request, Closure $next)
{
$replaced = [];
foreach ($request->all() as $key => $value) {
$replaced[studly_case($key)] = $value; //Arr::studly() for Laravel 6.x
}
$request->replace($replaced);
return $next($request);
}
This should rename all request intoStudlyCase
.
Answer
Solution:
Due to the answer of AnsellC I solved it by using Response Macros (https://laravel.com/docs/5.8/responses#response-macros). My solution looks as follows:
<?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);
});
}
}
It registers two macros for the REST API responses:success($data, $message)
anderror($message, $error_code, $status)
. There is a third macro extendingIlluminate\Support\Arr
to recursive changing the keys to camelCaserenameKeysCamel
.
As completion here is the code to handle incoming request by a middleware and change the JSON keys to 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;
}
}
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: videoxxx
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.