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 资源处理有点不了解。
好吧,在对 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 方法创建一个新的集合实例。我不知道解析函数的作用,除了文档提到它“使用服务容器将给定的类或接口名称解析为其实例”。我假设这意味着它确保正确通过课程?
无论如何,我希望这对未来的人们有所帮助。