Laravel管理不同的API响应

问题描述 投票:2回答:1

Explanation

用户使用条形码模型(可以是文章,包裹或库存货架)扫描条形码和系统响应。

return new BarcodeResource($barcode);

条形码资源根据条形码类解析条形码资源。每个barcodable模型返回不同的JSON资源。

// BarcodeResource.php

$modelResource = app()->makeWith(__NAMESPACE__ . '\\' . class_basename($this->barcodable) . 'Resource', [
    'resource' => $this->barcodable
]);

return [
    'code' => $this->code,
    'model_type' => class_basename($this->barcodable),
    'model_data' => $modelResource
];

的情况下...

  • ...文章,我想打印包含那些文章的包
  • ...包装,我想打印位置(库存货架),包括文章和子包
  • ...库存货架,我想打印所有包裹

Problem

我想用递归资源来防止无限循环。

Article
  >> Package
      >> Article (infinity loop begins because package resource 
                  returns articles in spesific package)

Package
  >> Article
      >> Package (loop...)
  >> Inventory Shelf
      >> Package (loop...)
  >> Child package


Inventory Shelf
  >> Package
      >> Article
      >> Inventory Shelf (loop...)
      >> Child package

渴望加载和取消关系应该是一个解决方案,但我如何在正确的阶段取消设置?这甚至可以使用一个资源,还是应该创建多个资源(递归/正常)?


Tries

Extra attribute containing relations

我尝试了这个解决方案,但神奇的$this->relations属性在几次递归后变为整数1 ...

class PackageResource extends JsonResource
{
    private $relations;

    public function __construct($resource, array $relations = [])
    {
        parent::__construct($resource);
        $this->relations = $relations;
    }

    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'articles' => $this->when(in_array('articles', $this->relations), ArticleResource::collection($this->articles, $this->relations)),
            'children' => PackageResource::collection($this->children, $this->relations),
        ];
    }
php laravel eloquent eager-loading
1个回答
1
投票

我对类似情况的解决方案如下:在资源文件中,我总是根据请求属性with返回关系。这附加到请求如下:我需要UserOrdersProfile,但我还需要Area订单,而请求是这样的:

http://example.com/api/v1/user/234?with=user.orders,user.profile,orders.area

并在资源文件中类似的东西:

    public function toArray($request)
    {
        $return = [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
            'location' => $this->location,
            'active' => $this->isActive(),
            'level' => $this->level,
        ];

        if($request->has('with')){

            $relationships = [
                'orders'=>[OrderCollection::class, 'orders'],
                'area'=>[Area::class, 'area', 'area.admin'],
                'profile'=>[UserProfile::class, 'profile'],
            ];

            $with = explode(',', $request->with);

            foreach($relationships as $key => $relationship){
                if( in_array("user.".$key, $with) ){
                    $return[$key] = new $relationship[0]($this->{$relationship[1]});
                }
            }
        }

        $return['created'] = $this->created_at->toDateTimeString();

        return $return;
    }

另一种解决方案是向资源类添加额外的属性:

    protected $with = "";
    public function __construct(mixed $resource, $with="")
    {
        parent::__construct($resource);
    }

当您调用该资源时,您可以按以前的方式过滤它。我刚刚测试过,它对我有用。

希望有所帮助。

© www.soinside.com 2019 - 2024. All rights reserved.