railken/lem

v4.0.5 2024-04-09 04:44 UTC

README

Actions Status

在构建API时,以精确的方式组织逻辑,以提高代码的可读性和可维护性。

需求

PHP 8.1及以后版本。

安装

您可以通过输入以下命令使用Composer安装它:Composer

composer require railken/lem

该包将自动注册自己。

用法

首先您需要生成一个新的结构文件夹,使用

php artisan railken:make:manager app App\Foo.

现在您可以使用了。

use App\Foo\FooManager;

$manager = new FooManager();
$result = $manager->create(['name' => 'foo']);

if ($result->ok()) {
    $foo = $result->getResource();
} else {
    $result->getErrors(); // All errors go here.
}

如何在操作过程中遇到错误?当验证或授权失败时,将发生错误。它很酷的地方在于,您可以在每个过程中完全控制:使用ValidatorAuthorizer。当您检索错误时,您正在接收一个集合,这在开发API时非常好用。以下是一个示例

$manager = new FooManager();
$result = $manager->create(['name' => 'f'));

print_r($result->getErrors()->toArray());
/*
Array
    (
        [0] => Array
            (
                [code] => FOO_TITLE_NOT_DEFINED
                [attribute] => title
                [message] => The title is required
                [value] =>
            )

        [1] => Array
            (
                [code] => FOO_NAME_NOT_DEFINED
                [attribute] => name
                [message] => The name isn't valid
                [value] => f
            )
    )
*/

那么,关于授权部分呢?首先,我们必须编辑User类。

use Railken\Lem\Contracts\AgentContract;

class User implements AgentContract
{
    public function can($permission, $arguments = [])
    {
        return true;
    }
}

您可以设置您想要的can方法,如果使用权限库(如https://github.com/Zizaco/entrusthttps://github.com/spatie/laravel-permission)则更好。

如果不需要系统权限,只需简单地返回true。

use Railken\Lem\Agents\SystemAgent;

$manager = new FooManager(Auth::user());
$result = $manager->create(['title' => 'f']);

print_r($result->getErrors()->toArray());
/*
Array
    (
        [0] => Array
            (
                [code] => FOO_TITLE_NOT AUTHORIZED
                [attribute] => title
                [message] => You're not authorized to interact with title, missing foo.attributes.title.fill permission
                [value] =>
            )
    )
*

"foo.attributes.title.fill"传递给User::can(),如果返回false,结果将包含错误。

注意:如果您没有设置任何代理,则将使用SystemAgent(所有授权)。

有关更多信息,请参阅Authorizer

命令

  • 生成一组新文件:php artisan railken:make:manager [路径] [命名空间]。例如:php artisan railken:make:manager App "App\Foo"

管理器

这是主类,所有操作都是通过这个类执行的:创建、更新、删除、检索。这个类由以下组件组成:验证器、仓库、授权者、参数、序列化器

请参阅Manager

namespace App\Foo;

use Railken\Lem\Manager;
use Railken\Lem\Contracts\AgentContract;

class FooManager extends Manager
{
    /**
     * Class name entity
     *
     * @var string
     */
    public $entity = Foo::class;

    /**
     * Construct
     *
     * @param AgentContract|null $agent
     */
    public function __construct(AgentContract $agent = null)
    {
        parent::__construct($agent);
    }
}

模型

这是Eloquent模型,除了一个接口外没有变化。

namespace App\Foo;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Railken\Lem\Contracts\EntityContract;

class Foo extends Model implements EntityContract
{

    use SoftDeletes;

    /**
     * The table associated with the model.
     *
     * @var string
     */
    protected $table = 'foo';

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = ['name'];

    /**
     * The attributes that should be mutated to dates.
     *
     * @var array
     */
    protected $dates = ['deleted_at'];
}

仓库

这是一个仓库,其概念与Symfony的仓库非常相似,在这里编写所有的查询。

有关更多信息,请参阅Repository

namespace App\Foo;

use Railken\Lem\Repository;

class FooRepository extends Repository
{

    /**
     * Custom method
     *
     * @param string $name
     *
     * @return Foo
     */
    public function findOneByName($name)
    {
        return $this->findOneBy(['name' => $name]);
    }

}

验证器

这里是验证器,它同样很简单。每次调用创建/更新操作时都会调用validate()。记住:总是返回错误集合。当然,您可以添加特定的验证库并将其用于此处。

namespace App\Foo;

use Railken\Lem\Contracts\EntityContract;
use Railken\Lem\Contracts\ValidatorContract;
use Railken\Lem\ParameterBag;
use Illuminate\Support\Collection;
use App\Foo\Exceptions as Exceptions;


class FooValidator implements ValidatorContract
{

    /**
     * Validate
     *
     * @param EntityContract $entity
     * @param ParameterBag $parameters
     *
     * @return Collection
     */
    public function validate(EntityContract $entity, ParameterBag $parameters)
    {

        $errors = new Collection();

        if (!$entity->exists)
            $errors = $errors->merge($this->validateRequired($parameters));

        $errors = $errors->merge($this->validateValue($entity, $parameters));

        return $errors;
    }

}

序列化器

这个类将序列化您的模型

namespace App\Foo;

use Railken\Lem\Contracts\SerializerContract;
use Railken\Lem\Contracts\EntityContract;
use Illuminate\Support\Collection;
use Railken\Bag;

class FooSerializer implements SerializerContract
{

	/**
	 * Serialize entity
	 *
	 * @param EntityContract $entity
	 *
	 * @return Bag
	 */
    public function serialize(EntityContract $entity, Collection $select)
    {
        $bag = (new Bag($entity->toArray()))->only($select->toArray());

		return $bag;
	}

}