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'),
]);
}
}
所以我创建了一个 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'),
]);
}
}