Промежуточное ПО Laravel для форматирования ключей массива ответов - PullRequest
0 голосов
/ 21 октября 2019

Я создаю Laravel API, и мне не нравится форматирование переменных с подчеркиванием (угловой интерфейс). Поэтому я подумал, что создаю промежуточное ПО, которое переименовывает все ключи json с подчеркиванием, удаляя их и используя заглавные буквы:

Я создал рекурсивную функцию, которая должна выполнять переименование. Но у меня проблемы с объектом ответа и / или массивом данных. И я почти уверен, что есть более понятный способ, о котором я не знаю?!

Вот мое промежуточное программное обеспечение:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Log;

class ProcessOutgoingJsonMiddleware
{
    /**
     * Handle an outgoing response.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $response = $next($request);

        if (is_array($response->getData()))
        {
            // Fetch json data
            $json_array = $this->rename_keys($response->getData());

            // Create changed response
            $response->setData($json_array);
        }

        return $response;
    }

    public function rename_keys($array) {
        $newArray = array();
        foreach($array as $key => $value) {
            $key = str_replace('_','',ucwords($key,'_'));
            if(is_array($value)) $value = $this->rename_keys($value);
            $newArray[$key] = $value;
        }
        return $newArray;
    }
}

Я даже не получаю сообщение об ошибке. Это просто не работает. Я использовал неправильный метод класса JsonResponse (https://laravel.com/api/5.8/Illuminate/Http/JsonResponse.html)? или есть проблема с моей рекурсивной функцией?

Заранее спасибо за помощь.:)

Ответы [ 2 ]

1 голос
/ 21 октября 2019

Если вы хотите отформатировать OUTPUT вашего приложения, лучше всего использовать макросы: https://laravel.com/docs/5.8/responses#response-macros или ресурсы Response https://laravel.com/docs/5.8/eloquent-resources#resource-responses

Из документов: Middlewares предоставляютудобный механизм фильтрации HTTP-запросов , поступающих в ваше приложение.

Но если вы действительно хотите сделать это с помощью промежуточного программного обеспечения:

public function handle($request, Closure $next)
{
    $response = $next($request);
    foreach($response->getOriginalContent()->getData() AS $key => $value) {
      //handle replacing of response here        
    }
    ...
}

Я не совсемпонять, что вы подразумеваете под «обработать исходящий ответ». на вашем docbloc, но если вы хотите отфильтровать входящий запрос JSON POST, попробуйте следующий метод:

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);
}

Это должно переименовать весь запрос в StudlyCase.

0 голосов
/ 22 октября 2019

Благодаря ответу 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;
    }
}

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...