rexlabs/laravel-smokescreen

3.4.1 2024-08-27 01:29 UTC

README

License: MIT Build Status Code Coverage Packagist

概览

Laravel Smokescreen 是一个用于转换您的 Laravel 模型和其他实体的软件包。

  • 转换 API 响应
  • 转换作业和事件负载
  • 最小化样板和引导
  • 支持嵌入数据的复杂关系
  • 支持关系预加载
  • 允许转换不同类型的资源
  • 可以处理序列化到可自定义的格式

此软件包将 rexlabs/smokescreen(纯 PHP)软件包与 Laravel 框架紧密集成,以在工作于 Laravel 应用程序时提供便利性和最小化样板。

使用方法

<?php
class MyController extends Controller
{
    public function index()
    {
        return Smokescreen::transform(Post::paginate());
    }
    
     public function show(Post $post)
     {
        return Smokescreen::transform($post);
     }
}
  • laravel-smokescreen 已引导到 Laravel 的应用容器中,因此您也可以将其类型提示以注入到控制器的构造函数或方法中。
  • 建议在控制器方法中使用外观(如上所示),在服务类中使用类型提示(如果需要)
  • 您还可以直接从容器中通过 app('smokescreen') 使用它,如上所示。
  • 由于我们实现了 Responsable 接口,您只需从任何控制器方法中返回 smokescreen 即可。

要求

  • PHP >= 7.0
  • Laravel >= 5.5

安装

此软件包目前托管在 RexSoftware 的私有 Packagist 仓库中。首先确保您已将您的 composer.json 配置为使用此仓库。

安装软件包

composer require rexlabs/laravel-smokescreen

此软件包将自动发现,无需其他配置。

配置

要将配置文件发布到您的 app/config 文件夹,请运行以下命令

php artisan vendor:publish --provider='Rexlabs\Laravel\Smokescreen\Providers\ServiceProvider --tag=config'

这将创建 config/smokescreen.php

<?php
return [
    // Set the default namespace for resolving transformers when
    // they are not explicitly provided.
    'transformer_namespace' => 'App\Transformers',
    
    // Override the default serializer to be used.
    // If not specified - the Smokescreen DefaultSerializer will be used.
    'default_serializer' => null,

    // Set the default request parameter key which is parsed for
    // the list of includes.
    'include_key' => 'include',
];

API

transform(): 设置要转换的资源

$smokescreen->transform(mixed $resource, mixed $transformer = null);

<?php
$smokescreen->transform(Post::find(1));
$smokescreen->transform(Post::all());
$smokescreen->transform(Post::paginate());
$smokescreen->transform(Post::find(1), new SomeOtherTransformer);
  • Smokescreen 将自动确定正在转换的资源类型。
  • 如果没有提供,它还将推断要使用的转换器类。

item(): 设置单个项目资源进行转换

$smokescreen->item(mixed $item, mixed $transformer = null);

<?php
$smokescreen->item(Post::find(1));
$smokescreen->item(Post::find(1), new SomeOtherTransformer);
  • 类似于 transform(),但仅接受一个项目。

collection(): 设置要转换的集合资源

$smokescreen->collection(mixed $collection, mixed $transformer = null);

<?php
$smokescreen->collection(Post::all());
$smokescreen->collection(Post::paginate());
$smokescreen->collection(Post::paginate(), new SomeOtherTransformer);
  • 类似于 transform(),但仅接受一个集合。

transformWith(): 设置之前设置的资源上要使用的转换器

$smokescreen->transformWith(TransformerInterface|callable $transformer);

<?php
$smokescreen->transform(Post::find(1))
    ->transformWith(new SomeOtherTransformer);
  • 这是向资源方法直接传递转换器的替代方法。

serializeWith(): 覆盖要使用的序列化程序

<?php
$smokescreen->serializeWith(new MyCustomSerializer);
  • 如果您计划使用与默认值不同的序列化程序,则需要设置此值。
  • 我们提供 DefaultSerializer 作为默认值,它返回嵌套在 "data" 节下的集合,并且没有嵌套的项目资源。
  • 您的自定义序列化程序应实现 SerializerInterface 接口。

loadRelationsVia(): 覆盖默认的 Laravel 关系加载器

$smokescreen->loadRelationsVia(RelationsLoaderInterface $loader);

<?php
$smokescreen->loadRelationsVia(new MyRelationsLoader);
  • 如果您计划使用与默认值不同的加载器,则需要设置此值。
  • 我们提供 RelationsLoader 作为默认值,它为集合资源预加载关系。
  • 您的自定义加载器应实现 RelationsLoaderInterface 接口并提供一个 load() 方法。

resolveTransformerVia(): 覆盖默认的转换器解析器

使用 $smokescreen->loadTransformersVia(TransformerResolverInterface $loader) 加载转换器。

<?php
$smokescreen->loadTransformersVia(new MyTransformerResolver);
  • 当资源上未显式定义转换器时,使用解析器。
  • 本包中的默认解析器会尝试在 smokescreen.transformer_namespace 路径中查找匹配的转换器类,并通过应用容器实例化。
  • 只有当你计划使用非默认解析器时,才需要设置此配置。
  • 你的自定义解析器应实现 TransformersLoaderInterface 接口,并提供一个 resolve(ResourceInterface) 方法。

response(): 访问生成的响应对象

$response = $smokescreen->response(int $statusCode = 200, array $headers = [], int $options = 0);

<?php
$smokescreen->response()
    ->header('X-Custom-Header', 'boo')
    ->setStatusCode(405);
  • 此方法返回一个 \Illuminate\Http\JsonResponse 对象,因此不可链式调用。
  • 所有支持的 JsonResponse 方法都可以应用。
  • 由于它是 JsonResponse 对象,你可以直接从控制器返回 response()
  • 你可以使用 withResponse($callback) 来应用更改,同时仍然支持链式调用。
  • 注意:第一次调用 response() 会缓存结果,这意味着后续调用传递的任何参数都将被忽略。你可以使用 clearResponse() 或直接操作 JsonResponse 对象。

freshResponse(): 生成一个新的响应对象

$response = $smokescreen->freshResponse(int $statusCode = 200, array $headers = [], int $options = 0);

  • response() 不同,此方法返回一个新鲜的非缓存 JsonResponse 对象(通过首先调用 clearResponse())。
  • 此方法返回一个 \Illuminate\Http\JsonResponse 对象,因此不可链式调用。有关链式方法,请参阅 withResponse()
  • 所有支持的 JsonResponse 方法都可以应用。

withResponse(): 应用生成的响应对象的更改

$smokescreen->withResponse(callable $apply);

<?php
$smokescreen->withResponse(function (JsonResponse $response) {
    $response->header('X-Crypto-Alert', 'all your coins are worthless!');
});
  • 提供一个回调函数,该函数接受一个 JsonResponse 对象并修改响应
  • 此方法与 response() 不同,是可链式的。

clearResponse(): 清除任何缓存的响应

$smokescreen->clearResponse();

<?php
$smokescreen->response();       // Data is generated, response object is built and cached
$smokescreen->response(500);    // NOPE - Cached, wont be changed!
$smokescreen->clearResponse();
$smokescreen->response(500);    // Response is re-generated
  • 重置任何缓存的响应对象

转换器

示例转换器

<?php
class PostTransformer extends AbstractTransformer
{
    protected $includes = [
        'user' => 'default|relation:user|method:includeTheDamnUser',
        'comments' => 'relation',
    ];

    public function transform(Post $post): array
    {
        return [
            'id' => $post->id,
            'user' => $this->when($post->user_id, [
                'id' => $post->user_id,
            ]),
            'title' => $post->title,
            'summary' => $post->summary,
            'body' => $post->body,
            'created_at' => utc_datetime($post->created_at),
            'updated_at' => utc_datetime($post->updated_at),
        ];
    }

    public function includeTheDamnUser(Post $post)
    {
        return $this->item($post->user); // Infer Transformer
    }

    public function includeComments(Post $post)
    {
        return $this->collection($post->comments, new CommentTransformer);
    }
}
  • 通过 $includes 数组声明你的可用包含项
  • 每个包含项可以接受以下指令中的 0 个或多个
    • default: 无论请求的包含项如何,此包含项始终启用
    • relation: 指示应预加载关系。如果关系名称不同,指定为 relation:othername
    • method: 默认情况下,包含键映射到 include{IncludeKey},你可以提供要使用的其他方法
  • 你的 transform() 方法应返回一个数组。
  • include{IncludeKey}(Model) 的格式定义你的包含方法 - 它们应返回一个 collection() 或一个 item()
  • when() 是一个简单的辅助方法,它接受一个条件并在条件为真时返回给定的值,在条件为假时返回 null(默认)。在上面的示例中,如果 $post 对象上没有设置 user_id,则 "user" 节点将为 null。

贡献

欢迎拉取请求。请确保代码符合 PSR 规范。Github 仓库

关于

  • 作者:Jodie Dunlop
  • 许可证:MIT
  • 版权所有 (c) 2018 Rex Software Pty Ltd