Как преобразовать сторонние данные API в ресурс для сбора в Laravel 5.6?

Я работал над созданием чистого интерфейса для нашего различного веб-приложения и столкнулся с трудностями, связанными с API-ресурсами Laravel, которые неправильно преобразовывают входящий массив json в коллекции laravel.

Я могу сделать это с одним ресурсом:

    namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;
use App\Product;

class ProductResource extends Resource
{
/**
* Transform the resource into an array.
*
* @param  \Illuminate\Http\Request  $request
* @return array
*/
public function toArray($request)
{
return [
'name' => $this->resource['product']['name'],
'description' => $this->resource['product']['description'],
'price' => $this->resource['product']['rental_rate']['price']
];

//return parent::toArray($request);
}
}

распечатать этот ответ:

{"name":"Arri Skypanel S60-C","description":"Arri Sky Panel S60-C 450w input with a 2000w tungsten equivalent & Combo Stand","price":"260.0"}

Однако попытка взять этот единственный предмет и превратить его в набор предметов никуда не денется.

Кто-нибудь понял, что мне не хватает?

Извлечение данных API выглядит следующим образом:

namespace App;
use GuzzleHttp\Exception\GuzzleException;
use GuzzleHttp\Client;

class ThirPartyAPI
{
private $url = 'https://api.third-party.com/api/v1/';

public function pull($query, $additionalParams) {
$client = new Client;
$result = $client->get($this->url . $query . $additionalParams, [
'headers' => [
'Content-Type' => 'application/json',
'X-AUTH-TOKEN' => env('CURRENT-AUTH-TOKEN'),
'X-SUBDOMAIN' => env('CURRENT-SUBDOMAIN')
]
]);
$array = json_decode($result->getBody()->getContents(), true);

return $array;
}
}

API возвращает много данных JSON.

Это модель продукта:

public function getAllProducts() {
try {

$productData = [];
$query = "/products?page=1&per_page=3&filtermode=active";
$additionalParams = "";
$productData = new ThirdPartyAPI;
$productData = $productData->pull($query, $additionalParams);

$productData = $productData['products'];

return ProductsResource::make($productData);
} catch (\Exception $ex) {
return $ex;
} catch (\Throwable $ex) {
return $ex;
}

}

Прямо сейчас я пытаюсь что-то сделать, чтобы преобразовать все возвращенные массивы во что-то, что я могу контролировать больше:

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\Resource;

class ProductsResource extends Resource
{
/**
* Transform the resource into an array.
*
* @param  \Illuminate\Http\Request  $request
* @return array
*/
public function toArray($request)
{
return [
'products' => $this->collection->mapInto(function($request) {
return[ 'name' => $this->resource['name'],
'description' => $this->resource['description'],
'price' => $this->resource['rental_rate']['price']
];
})
];

}

Однако var_dumping данные просто возвращают это:

object(App\Http\Resources\ProductsResource)[200]
public 'resource' =>
array (size=3)
0 =>
array (size=37)
'id' => int 164
'name' => string '10A Dimmer' (length=10)
[Lots of data]
...
'sale_rates' =>
array (size=0)
...
1 => .....
[cont]
public 'with' =>
array (size=0)
empty
public 'additional' =>
array (size=0)
empty

Я пробовал различные формы преобразования данных в возвращаемой информации json, и у меня не было много результатов, кроме ошибок и запутанного бизнеса. Я немного сомневаюсь в том, как Laravel обрабатывает обработку ресурсов API.

2

Решение

Итак, после некоторого изучения методов Laravel ‘make’, ‘mapinto’ и ‘map’ для коллекций, я в итоге получил рабочий результат этого преобразования здесь:

$productData = ThirdPartyAPI;
$productData = $productData->pull($query, $additionalParams);
$productData = $productData['products'];

$products = collect($productData)->map(function($row){
return ProductsResource::make($row)->resolve();
});
var_dump($products);

Это var_dump возвращает это:

object(Illuminate\Support\Collection)[228]
protected 'items' =>
array (size=3)
0 =>
array (size=3)
'name' => string '10A Dimmer' (length=10)
'description' => string '10amp Dimmer (Max 2.4k)' (length=23)
'price' => string '5.0' (length=3)
....
[And so on]

Исходная информация, которая была возвращена, была многомерным массивом.

$returnedArray = array(
['array' => 1, 'name' => 'name', etc],
['array' => 2, 'name' => 'name, etc]
);

Метод коллекции Laravel по умолчанию превращает только верхний массив в коллекцию. Чтобы должным образом иметь возможность контролировать результаты с помощью моделей ресурсов, мы должны преобразовать весь набор массивов в коллекции, что означает, что нам нужно перебирать возвращаемые данные, чтобы преобразовать их во что-то, что laravel может правильно прочитать. Это то, что делает метод карты.

Согласно документы it, ‘метод map выполняет итерацию по коллекции и передает каждое значение заданному обратному вызову. Функция обратного вызова может свободно изменять элемент и возвращать его, формируя новую коллекцию измененных элементов.

Метод make создает новый экземпляр коллекции. Я не знаю, что делает функция разрешения, за исключением того, что документы отметим, что он «разрешает данный класс или имя интерфейса в своем экземпляре с использованием сервисного контейнера». Я собираюсь предположить, что это означает, что он гарантирует, что проходит через класс правильно?

В любом случае, я надеюсь, что это поможет людям в будущем.

1

Другие решения

Других решений пока нет …