Skip to content

Commit

Permalink
perf: format
Browse files Browse the repository at this point in the history
  • Loading branch information
jiannei committed Oct 14, 2023
1 parent d0b5d66 commit a18fcd1
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 21 deletions.
63 changes: 63 additions & 0 deletions src/Contract/ResponseFormat.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<?php

namespace Jiannei\Response\Laravel\Contract;

use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Http\Resources\Json\ResourceCollection;
use Illuminate\Pagination\AbstractCursorPaginator;
use Illuminate\Pagination\AbstractPaginator;

interface ResponseFormat
{
/**
* @return JsonResponse
*/
public function response(): JsonResponse;

/**
* Get formatted data.
*
* @return array|null
*/
public function get(): ?array;


/**
*
* Format data structures.
*
* @param mixed|null $data
* @param string $message
* @param int|\BackedEnum $code
* @param $error
* @return $this
*/
public function data(mixed $data = null, string $message = '', int|\BackedEnum $code = 200, $error = null): static;


/**
* Format paginator data.
*
* @param AbstractPaginator|AbstractCursorPaginator|Paginator $resource
* @return array
*/
public function paginator(AbstractPaginator|AbstractCursorPaginator|Paginator $resource): array;

/**
* Format collection resource data.
*
* @param ResourceCollection $collection
* @return array
*/
public function resourceCollection(ResourceCollection $collection): array;

/**
* Format JsonResource Data.
*
* @param JsonResource $resource
* @return array
*/
public function jsonResource(JsonResource $resource): array;
}
13 changes: 13 additions & 0 deletions src/Providers/LaravelServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,26 @@

namespace Jiannei\Response\Laravel\Providers;

use Illuminate\Foundation\Application;
use Illuminate\Support\ServiceProvider;
use Jiannei\Response\Laravel\Contract\ResponseFormat;
use Jiannei\Response\Laravel\Support\Format;

class LaravelServiceProvider extends ServiceProvider
{
public function register()
{
$this->setupConfig();

$this->app->singleton(ResponseFormat::class, function (Application $app) {
$formatter = $app->config->get('response.format.class');
$config = $app->config->get('response.format.config');

return match (true) {
class_exists($formatter) && is_subclass_of($formatter, ResponseFormat::class) => new $formatter($config),
default => new Format($config),
};
});
}

protected function setupConfig()
Expand Down
2 changes: 1 addition & 1 deletion src/Support/Facades/Format.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,6 @@ class Format extends IlluminateFacade
{
protected static function getFacadeAccessor()
{
return config('response.format.class', \Jiannei\Response\Laravel\Support\Format::class);
return \Jiannei\Response\Laravel\Contract\ResponseFormat::class;
}
}
44 changes: 24 additions & 20 deletions src/Support/Format.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Lang;
use Illuminate\Support\Traits\Macroable;
use Jiannei\Response\Laravel\Contract\ResponseFormat;

class Format
class Format implements ResponseFormat
{
use Macroable;

protected ?array $data = null;
protected int $statusCode = 200;


public function __construct(protected array $config = [])
{
}

/**
* Return a new JSON response from the application.
*
Expand Down Expand Up @@ -148,7 +154,7 @@ protected function formatMessage(int $code, string $message = ''): ?string
$localizationKey = join('.', [Config::get('response.locale', 'enums'), $code]);

return match (true) {
! $message && Lang::has($localizationKey) => Lang::get($localizationKey),
!$message && Lang::has($localizationKey) => Lang::get($localizationKey),
default => $message
};
}
Expand Down Expand Up @@ -269,27 +275,25 @@ protected function formatError(?array $error): object|array
*/
protected function formatDataFields(array $data): array
{
$formatConfig = Config::get('response.format.config', []);
return tap($data, function (&$item) {
foreach ($this->config as $key => $config) {
if (!Arr::has($item, $key)) {
continue;
}

foreach ($formatConfig as $key => $config) {
if (! Arr::has($data, $key)) {
continue;
}
$show = $config['show'] ?? true;
$alias = $config['alias'] ?? '';

$show = $config['show'] ?? true;
$alias = $config['alias'] ?? '';
if ($alias && $alias !== $key) {
Arr::set($item, $alias, Arr::get($item, $key));
$item = Arr::except($item, $key);
$key = $alias;
}

if ($alias && $alias !== $key) {
Arr::set($data, $alias, Arr::get($data, $key));
$data = Arr::except($data, $key);
$key = $alias;
if (!$show) {
$item = Arr::except($item, $key);
}
}

if (! $show) {
$data = Arr::except($data, $key);
}
}

return $data;
});
}
}
9 changes: 9 additions & 0 deletions tests/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ protected function defineEnvironment($app)
if ($this instanceof \P\Tests\Unit\CustomFormatTest) {
$app['config']->set('response.format', [
'class' => \Jiannei\Response\Laravel\Tests\Support\Format::class,
'config' => [
// key => config
'status' => ['alias' => 'status', 'show' => false],
'code' => ['alias' => 'code', 'show' => true],
'message' => ['alias' => 'msg', 'show' => true],
'error' => ['alias' => 'error', 'show' => false],
'data' => ['alias' => 'data', 'show' => true],
'data.data' => ['alias' => 'data.data', 'show' => true], // rows/items/list
]
]);
}
}
Expand Down
24 changes: 24 additions & 0 deletions tests/Unit/CustomFormatTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
* with this source code in the file LICENSE.
*/

use Jiannei\Response\Laravel\Support\Facades\Format;
use Jiannei\Response\Laravel\Support\Facades\Response;

test('add extra field', function () {
Expand All @@ -18,3 +19,26 @@
->and($response->getData(true))->toHaveKey('extra')
->and($response->getData(true)['extra'])->toHaveKey('time');
});

/**
* 'class' => \Jiannei\Response\Laravel\Tests\Support\Format::class,
* 'config' => [
* // key => config
* 'status' => ['alias' => 'status', 'show' => false],
* 'code' => ['alias' => 'code', 'show' => true],
* 'message' => ['alias' => 'msg', 'show' => true],
* 'error' => ['alias' => 'error', 'show' => false],
* 'data' => ['alias' => 'data', 'show' => true],
* 'data.data' => ['alias' => 'data.data', 'show' => true], // rows/items/list
* ]
*/
test('hide some field', function () {
// 隐藏 status,message 字段名称修改成 msg
$data = Format::data()->get();

expect($data)->toMatchArray([
'code' => 200,
'data' => (object)[],
'msg' => '操作成功'
]);
});

0 comments on commit a18fcd1

Please sign in to comment.