saltid / lumen-repository

Lumen的仓库模式。

v1.0.2 2023-02-21 10:59 UTC

This package is auto-updated.

Last update: 2024-09-22 07:01:03 UTC


README

系统要求

Composer

此软件包可在 Packagist 上找到,并可以使用 Composer 安装。

$ composer require saltid/lumen-repository

接口

以下接口实现的 SaltId\LumenRepository\Repositories\AbstractRepository

SaltId\LumenRepository\Criteria\AbstractCriteria 实现

并且 SaltId\LumenRepository\Criteria\RequestCriteria 继承了 SaltId\LumenRepository\Criteria\AbstractCriteria

标准用于过滤数据,例如默认的标准是 RequestCriteria,负责处理搜索、排序等。你可以通过扩展 AbstractCriteria 或实现 CriteriaInterface 来创建自己的标准,并使用方法 pushCriteria(CriteriaInterface $criteria): static; 将其推送到仓库中。

用法

您的 模型 应实现 \SaltId\LumenRepository\Contracts\TransformableInterface 并实现 transform(): array 方法

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use SaltId\LumenRepository\Contracts\TransformableInterface;

class Article extends Model implements TransformableInterface
{
    // your model content.

    public function transform(): array
    {
        // return your model toArray() as default
        return $this->toArray();

        // or you can transform it into anything you wanted.
        // for example :
        //return [
        //    'my_id' => $this->id,
        //    'my_title' => $this->title,
        //    'my_relation_to_other_model_id' => $this->getOtherModel()?->id,
        //    'my_relation_to_other_model_to_array' => $this->getOtherModel()?->toArray(),
        //    'my_relation_to_other_model_to_transform' => $this->getOtherModel()?->transform(),
        //];
    }
}

?>

创建 转换器 类,并扩展它为 SaltId\LumenRepository\Transformers\TransformerAbstract,它看起来像这样

<?php

namespace App\Transformers;

use SaltId\LumenRepository\Transformers\TransformerAbstract;

class ArticleTransformer extends TransformerAbstract
{

}

创建 展示器 类,并扩展它为 SaltId\LumenRepository\Presenter\FractalPresenter,并重写抽象方法 getTransformer(): ?TransformerAbstract,它看起来像这样

<?php

namespace App\Presenters;

use App\Transformers\ArticleTransformer;
use SaltId\LumenRepository\Presenter\FractalPresenter;
use SaltId\LumenRepository\Transformers\TransformerAbstract;

class ArticlePresenter extends FractalPresenter
{
    public function getTransformer(): ?TransformerAbstract
    {
        return app(ArticleTransformer::class);
    }
}

扩展您的 仓库 类为 SaltId\LumenRepository\Repositories\AbstractRepository

<?php

namespace App\Repositories;

use SaltId\LumenRepository\Repositories\AbstractRepository;
use SaltId\LumenRepository\Contracts\PresenterInterface;

class ArticleRepository extends AbstractRepository
{
    protected array $searchableFields = [
        'title',
        'description'
    ];
    
    public function presenter(): ?PresenterInterface
    {
        // return should be implement PresenterInterface
        return app(ArticlePresenter::class);
    }
}

现在,是时候使用我们的仓库了!但首先,这可能不是一种好做法,因为我们直接从控制器中使用了仓库,你可以创建一个服务或用例类,并注入 RepositoryInterface

在你的控制器中

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use SaltId\LumenRepository\Contracts\RepositoryInterface;

class ArticleController extends Controller
{
    protected RepositoryInterface $repository;

    public function __construct(RepositoryInterface $repository)
    {
        $this->repository = $repository;
    }

    // Or you can add the line code above in \App\Http\Controllers\Controller
    // so you don't need the declare it everytime. It's up to you.

    public function index(): array
    {
        return $this->repository->all();

        //return $this->repository->paginate();
    }

    // you may create FormRequest for validation.
    public function store(Request $request): array
    {
        return $this->repository->create($request->all());
    }

    public function show(int $id): array
    {
        return $this->repository->find($id);
    }

    public function update(Request $request, int $id): array
    {
        return $this->repository->update($request->all(), $id);
    }

    public function destroy(int $id): array
    {
        return $this->repository->delete($id);
    }
}

routes/(web|api).php

<?php

/** @var \Laravel\Lumen\Routing\Router $router */

/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It is a breeze. Simply tell Lumen the URIs it should respond to
| and give it the Closure to call when that URI is requested.
|
*/

$router->get('/article', 'ArticleController@index');
$router->post('/article', 'ArticleController@store');
$router->get('/article/{id}', 'ArticleController@show');
$router->put('/article/{id}', 'ArticleController@update');
$router->delete('/article/{id}', 'ArticleController@destroy');

由于我们在控制器中注入了 RepositoryInterface,我们将使用 service provider 来告诉控制器我们在控制器中将使用哪个仓库。

创建名为 RepositoryServiceProvider 的服务提供者类

<?php

namespace App\Providers;

use App\Http\Controllers\ArticleController;
use App\Models\Article;
use App\Repositories\ArticleRepository;
use Illuminate\Support\ServiceProvider;
use SaltId\LumenRepository\Contracts\RepositoryInterface;

class RepositoryServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app
            ->when(ArticleController::class)
            ->needs(RepositoryInterface::class)
            ->give(function() {
                return new ArticleRepository(new Article());
            });
    }
}

上面的代码,我们告诉应用程序当 ArticleController 执行并需要 RepositoryInterface 时,它会将带有模型 ArticleArticleRepository 传递给控制器。别忘了在 bootstrap/app.php 中注册 RepositoryServiceProvider

就这样!现在你在 routes/(web|api).php 中定义的端点有了 CRUD。