Laravel 5.6 如何将第三方 API 数据转换为集合资源?

Mug*_*uck 5 php api-design data-conversion laravel-5

我一直致力于为我们的各种 Web 应用程序创建一个干净的界面,但我遇到了 Laravel 的 API 资源无法将传入的 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

打印此响应输出:

{"name":"Arri Skypanel S60-C","description":"Arri Sky Panel S60-C 450w input with a 2000w tungsten equivalent & Combo Stand","price":"260.0"}
Run Code Online (Sandbox Code Playgroud)

然而,试图将这个单一的项目变成一个项目的集合是行不通的。

有人知道我错过了什么吗?

拉取 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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;
    }

} 
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试将所有返回的数组转换为我可以控制的更多内容:

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']
                ];
            })
        ];

    }
Run Code Online (Sandbox Code Playgroud)

但是 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
Run Code Online (Sandbox Code Playgroud)

我在返回的 json 信息上尝试了各种形式的数据转换,除了错误和混乱的业务之外,并没有得到很多结果。我对 Laravel 如何处理 API 资源处理有点不了解。

Mug*_*uck 5

好吧,在对 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);
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

返回的初始信息是一个多维数组。

$returnedArray = array(
    ['array' => 1, 'name' => 'name', etc],
    ['array' => 2, 'name' => 'name, etc]
);
Run Code Online (Sandbox Code Playgroud)

Laravel 的默认集合方法仅将顶部数组转换为集合。为了能够通过 Resource 模型正确控制结果,我们必须将整个数组集转换为集合,这意味着我们必须迭代返回的数据,将其转换为 Laravel 可以正确读取的数据。这就是 map 方法的作用。

根据文档,“map 方法迭代集合并将每个值传递给给定的回调。回调可以自由修改项目并返回它,从而形成修改项目的新集合'

make 方法创建一个新的集合实例。我不知道解析函数的作用,除了文档提到它“使用服务容器将给定的类或接口名称解析为其实例”。我假设这意味着它确保正确通过课程?

无论如何,我希望这对未来的人们有所帮助。