Laravel,可重用 API 资源方法

Laravel, Reusable API Resource method

所以我创建了一个 API 资源,并且在 toArray() 方法中,我过滤了通过查询字符串返回的属性。我希望能够为我的大部分 API 资源执行此操作,因此将其移至可重用方法中是有意义的。这样做的最佳方法是什么?

我正在考虑扩展基础 Resource 但我不确定我将如何去做。还是应该将其移动到服务 class 或存储库中?

我的方法如下;

public function toArray($request)
{
    if($request->fields) {
        $fields         = [];
        $selectedFields = explode(',', $request->fields);
        foreach($selectedFields as $field) {
            if(isset($this->{$field})) {
                $fields[$field] = $this->{$field};
            }
        }
        return $fields;
    } else {
        return parent::toArray($request);
    }
}

理想情况下,我想做类似...

public function toArray($request)
{
    if($request->fields) {
        return parent::filterFields($request); // Not sure whether it should be parent::, $this or something else?
    } else {
        return parent::toArray($request); // Not sure whether it should be parent::, $this or something else?
    }

    // or event just
    return parent::filterFields($request); // Not sure whether it should be parent::, $this or something else?
}

完整 类:

ProjectResource.php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class ProjectResource extends Resource
{

    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function toArray($request)
    {
        dd(parent::filterFields());
        // or
        dd($this->filterFields());

        if($request->fields) {
            $fields         = [];
            $selectedFields = explode(',', $request->fields);
            foreach($selectedFields as $field) {
                if(isset($this->{$field})) {
                    $fields[$field] = $this->{$field};
                }
            }
            return $fields;
        } else {
            return parent::toArray($request);
        }
    }
}

Test.php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class Test extends Resource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request
     * @return array
     */
    public function filterFields($request)
    {
        return 'test';
    }
}

谢谢!

如果要扩展 class,则可以使用 parent::$this->。不同之处在于 parent 将始终引用父级 class,而 $this 仅在当前 class 上不存在该方法时才引用父级。因此,使用 $this 允许扩展方法和属性。

示例:

<?php
class A {
    public function test() {
        echo 'A';
    }
}

class B extends A {
    public function test() {
        echo 'B';
    }

    public function callParent(){
        parent::test();
    }

    public function callThis() {
        $this->test();
    }
}


$b = new B();
$b->callParent(); // Echoes A
$b->callThis(); // Echos B

在您更新的 class 表示中,您有两个 classes 扩展 Resource 但 ProjectResource 将不知道 Test 中的方法。您将需要 ProjectResource 来扩展 Test,它也将继承 Resource 的方法,因为 Test 扩展了 Resource(多重继承)。


除此之外,您的实施方式将取决于意见,您有很多选择。你可以扩展一个抽象class,你可以使用一个专用的过滤class,或者你可以使用一个特征。

您可以扩展资源

  <?php
        
        namespace App\Http\Resources;
        
        use App\Http\Resources\Product as ProductResource;
        
        class ProductQuantity extends ProductResource
        {
            /**
             * Transform the resource into an array.
             *
             * @param  \Illuminate\Http\Request  $request
             * @return array
             */
            public function toArray($request)
            {
                $parent = parent::toArray($request);
        
                return array_merge($parent, [
                    'depotsQuantity' => $this->warehouses->sum('pivot.quantity'),
                ]);
            }
        }