Laravel управляет различными ответами API - PullRequest
2 голосов
/ 06 марта 2019

Объяснение

Пользователь сканирует штрих-код и системные ответы с помощью штрихкодируемой модели (может быть "Статья", "Упаковка" или "Полка инвентаризации").

return new BarcodeResource($barcode);

Ресурс штрих-кода разрешает ресурс штрихкодирования на основе класса штрихкодирования.Каждая штрих-кодовая модель возвращает разные 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
];

В случае ...

  • ... Статья, я хотел бы напечатать пакеты, содержащие такие статьи
  • ... Пакет, я хотел бы напечатать местоположение (полка инвентаря), включенные статьи и дочерние пакеты
  • ... Инвентарная полка, я хотел бы напечатать все пакеты

Проблема

Я хочу предотвратить бесконечные циклы с рекурсивными ресурсами.

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

Дополнительный атрибут, содержащий отношения

Я пробовал это решение,но волшебным образом $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),
        ];
    }

1 Ответ

1 голос
/ 07 марта 2019

Мое решение для подобной ситуации было следующим: В файлах ресурсов я всегда возвращаю отношения на основе свойства запроса with. Это прикреплено к запросу следующим образом: Мне нужны User с Orders и Profile, но мне также нужно 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);
    }

Чем, когда вы вызываете этот ресурс, вы можете отфильтровать его предыдущим способом. Я только что проверил, и у меня это сработало.

Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...