kouks/laravel-casters

提供了一种方便的方式来将您的模型转换为API用途。

1.1.0 2016-11-07 21:17 UTC

This package is not auto-updated.

Last update: 2024-09-28 20:09:10 UTC


README

Scrutinizer Code Quality Latest Version on Packagist Build Status StyleCI

内容

安装

Composer

打开您的控制台并cd到您的Laravel项目目录。运行

composer require kouks/laravel-casters

是的,您现在基本上已经准备好开始使用了...

使用

创建转换器

您几乎可以在任何地方放置转换器,但我认为您应该将它们放在app/Casters目录中。现在创建一个新的PHP类,我们将在这里转换Post模型。 假设我们的模型只有idtitlebodyactive数据库列,以及时间戳。

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    //
}

很好!现在我们可以添加我们的第一个转换规则。

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'title',
        ];
    }
}

这个转换器只会转换标题列,其内容保持不变。更多关于制作规则的信息,请参阅下一节。

制作您的规则

让我们继续了解如何制作您自己的规则,目前有四种方法可以做到这一点。

简单的转换/重命名列

在上一个部分中有一个简单转换规则的例子。让我们再次回顾并添加一些内容。

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'title',
            'body' => 'long_text',
        ];
    }
}

此规则将完全保留title列不变,并将body列重命名为long_text,然而内容保持不变。

使用转换查询

类似于Laravel的验证规则,您可以使用查询来进行转换。

namespace App\Casters;

use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'active' => '!name:is_active|type:bool',
        ];
    }
}

注意转换规则前的!。这意味着我们想使用一个查询。这个简单的查询将active列重命名为is_active,并将其内容转换为布尔值。有关转换查询的所有文档可以在转换查询部分找到。

使用闭包进行转换

作为转换规则的值,您可以指定一个闭包,该闭包将确定要返回的数据。

namespace App\Casters;

use App\Post;
use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'text' => function (Post $post) {
                return str_limit($post->body, 100);
            },
        ];
    }
}

这个特定的查询将转换一个新的列body,并将其内容设置为闭包返回的值。在这种情况下,- 将帖子内容限制为100个字符。请注意,在闭包参数中给出了正在转换的模型的实例。

使用方法进行转换

您甚至可以使用转换器类上的其他方法来确定要转换的内容。

namespace App\Casters;

use App\Post;
use Koch\Casters\Caster;

class PostCaster extends Caster
{
    public castRules()
    {
        return [
            'draft' => '@isDraft',
        ];
    }
    
    public function isDraft(Post $post)
    {
        return ! $post->active;
    }
}

注意@符号 - 它是用来确定我们想使用转换器类方法来进行转换的。此转换(类似于闭包转换)创建了一个新的列draft,在这个例子中,它是active列的否定。在这种情况下,您也得到了模型实例。

实际转换

实际的转换非常简单,目前有两种方法可以转换您的数据。

转换单个模型

让我们有一个控制器动作show,它将转换我们的模型,并将其作为JSON返回。

...

class PostController extends Controller
{
    public function show(Post $post, PostCaster $caster)
    {
        return $caster->cast($post);
    }
}

请注意,您可以使用DI(依赖注入)为您的转换器,就像Laravel中的任何内容一样。然后您调用一个单独的cast方法,并在参数中提供您的模型实例。如果我们组合所有示例转换器,返回的JSON可能如下所示

{
  "id": 1,
  "title": "Some title",
  "long_text": "Some long text...",
  "text": "Some long text...",
  "active": true,
  "draft": false,
  "updated_at": {
    "date": "2016-11-01 00:38:03.000000",
    "timezone_type": 3,
    "timezone": "UTC"
  },
  "created_at": {
    "date": "2016-08-06 17:58:09.000000",
    "timezone_type": 3,
    "timezone": "UTC"
  }
}

请注意,在上面的例子中,text字段将限制为100个字符。

转换集合

您可以将集合以与单个模型相同的方式转换。唯一的区别是您将返回一个转换模型的数组,而不是一个单一的模型。

从模型实例直接转换

此包提供了 Koch\Casters\Behavior\Castable 特性,它允许您按照以下方式转换单个模型

$post->cast($caster);

并且直接从您查询中转换集合

Post::cast($caster);

请注意,如果您在模型中指定了转换器的完整类路径,您可以完全省略 caster 变量。

...
class Post extends Model
{
    use Castable;

    protected $caster = App\Casters\PostCaster::class;
}

让您做这些花哨的事情

$post->cast();

Post::cast();

如果您遵循将转换器存储在 app/Casters 目录以及命名约定的约定,此包将尝试在该位置查找相关的转换器 - 这使您可以省略 caster 属性。

转换关系

显然,有一种方法可以转换关系。假设有一个相关模型 Comments,它与我们的 Post 模型有一个 多对一 关系。还假设有一个 CommentCaster 已经设置。看以下代码

namespace App\Casters;

use App\Post;
use Koch\Casters\Caster;

class PostCaster extends Caster
{
    protected $commentCaster;
    
    public function __construct(CommentCaster $commentCaster)
    {
        $this->commentCaster = $commentCaster;
    }
    
    public castRules()
    {
        return [
            'comments' => function (Post $post) {
                return $this->commentCaster->cast($post->comments);
            },
        ];
    }
}

请注意,即使在这里,您也可以利用 Laravel 的 依赖注入。您现在创建一个新的列 comments,然后通过闭包填充它。这个闭包使用注入的转换器来转换评论关系。您也可以通过方法进行相同的转换。

请注意,防止循环转换。目前,没有检查这一点。所以,如果您在 PostCaster 上转换 comments 关系,然后反过来也这样做,您将得到一个 500。 欢迎提交一个 PR 来纠正这个问题。

转换查询

目前,只有两个查询。我愿意听取添加更多查询的建议。

  • name:new_name
  • type:new_type - 接受 intstringboolfloat

抽象

存在一个 Koch\Casters\Contracts\Caster 接口,您可以用它,例如,与仓储模式一起使用,其中有一个父 Repository 类处理任何模型周围的所有事情,包括转换它。您可能希望通过 PostRepository 构造函数注入转换器,在这种情况下,父类将需要该契约。

常见问题解答

没有人问过我关于这个包的问题,所以我无法确定问题的频率。