自定义Laravel 5.5 Api资源集合分页

时间:2018-01-04 11:55:40

标签: laravel-5.5

我一直在使用laravel api资源。默认情况下,laravel提供链接和元数据,如下所示。

"links": {
    "first": "https://demo.test/api/v2/taxes?page=1",
    "last": "https://demo.test/api/v2/taxes?page=4",
    "prev": null,
    "next": "https://demo.test/api/v2/taxes?page=2"
},
"meta": {
   "current_page": 1,
   "from": 1,
   "last_page": 4,
   "path": "https://demo.test/api/v2/taxes",
   "per_page": 2,
   "to": 2,
   "total": 8
} 

但我不想要这个,我希望我想要像

这样的东西
"pagination": {
  "total": 8,
  "count": 8,
  "per_page": 25,
  "current_page": 1,
  "total_pages": 1
}

我能够获得此信息,但如果我return TaxResource::collection($taxes);,我将无法获得此信息。即使我有自定义收集方法

 public static function collection($resource)
    {
       $resource->pagination = [
        'total' => $resource->total(),
        'count' => $resource->count(),
        'per_page' => $resource->perPage(),
        'current_page' => $resource->currentPage(),
        'total_pages' => $resource->lastPage()
       ];
        return parent::collection($resource);
    }

它没有给出我想要的东西。但如果我通过(TaxResource::collection($taxes))->pagination;引用,我就可以得到它。但我想在return TaxResource::collection($taxes);

时返回它

6 个答案:

答案 0 :(得分:8)

我对你的问题很感兴趣并花一些时间来解决它。我想有很多工作要做,以便将来改进 Eloquent:API资源' 功能。

要解决此问题,我必须使用资源集合而不是资源

  

但是,如果您需要自定义随集合返回的元数据,则需要定义资源集合

php artisan make:资源税 - 收藏

php artisan make:resource TaxCollection

<强>路线:

Route::get('/get-taxes', function () {
    $taxes = Taxes::paginate();
    return new TaxCollection($s);
});

<强> TaxCollection.php:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Resources\Json\ResourceCollection;

class TaxCollection extends ResourceCollection
{        
    public function toArray($request)
    {
        return [
        'data' => $this->collection,
        'pagination' => [
            'total' => $this->total(),
            'count' => $this->count(),
            'per_page' => $this->perPage(),
            'current_page' => $this->currentPage(),
            'total_pages' => $this->lastPage()
        ],
    ];
    }  

    // Using Laravel < 5.6
    public function withResponse($request, $response)
    {
        $originalContent = $response->getOriginalContent();
        unset($originalContent['links'],$originalContent['meta']);
        $response->setData($originalContent);
    }

    // Using Laravel >= 5.6
    public function withResponse($request, $response)
    {
        $jsonResponse = json_decode($response->getContent(), true);
        unset($jsonResponse['links'],$jsonResponse['meta']);
        $response->setContent(json_encode($jsonResponse));
    }
}

这解决了问题,但现在有了新问题: 与资源不同,我不知道如何修改资源集合中的toArray字段,本手册仅显示我们发送'data' => $this->collection的示例未修改的集合(资源集合允许我们更改元数据)。因此,如果我们只使用资源,那么我们可以修改收集数据,但不能修改元数据。

答案 1 :(得分:6)

接受的答案对我不起作用(在Laravel 5.6中),但我找到了更好的方式恕我直言。

在您的ResourceCollection构造函数中保存分页信息,并将Paginator资源替换为基础Collection。

<强> TaxCollection.php:     

printf

答案 2 :(得分:1)

您还可以扩展JsonResource,AnonymousResourceCollection,ResourceCollection以及最后的PaginatedResourceResponse

答案 3 :(得分:0)

@ yrv16 Laravel 5.6版本:

public function withResponse($request, $response)
{
    $jsonResponse = json_decode($response->getContent(), true);
    unset($jsonResponse['links'],$jsonResponse['meta']);
    $response->setContent(json_encode($jsonResponse));
}

答案 4 :(得分:0)

所以我发现在PHP中,您实际上可以调用祖父母函数而无需进行反射或其他解决方法。

鉴于TaxCollection扩展了ResoureCollection,而后者又扩展了JsonResource,我们实际上可以绕过处理分页的ResourceCollection方法。

class TaxCollection extends ResourceCollection
{        
    public function toArray($request)
    {
        return [
        'data' => $this->collection,
        'pagination' => [
            'total' => $this->total(),
            'count' => $this->count(),
            'per_page' => $this->perPage(),
            'current_page' => $this->currentPage(),
            'total_pages' => $this->lastPage()
        ],
    ];
    }  

    public function toResponse($request)
    {
        return JsonResource::toResponse($request);
    }
}

toResponse方法调用不是静态的,而是调用祖父母JsonResource :: toResponse方法,就像parent :: toResponse将调用ResourceCollection的toResponse(..)实例方法一样。

这将从JSON响应中删除所有多余的分页字段(链接,元等),并允许您根据需要在toArray($request)

中自定义响应

答案 5 :(得分:0)

JsonResource类带有一个Additional()方法,该方法可让您指定使用资源时希望作为响应一部分的任何其他数据:

   Route::get('/get-taxes', function () {
    $taxes = Taxes::paginate();
    return new TaxCollection($s)->additional([
       'pagination' => [
          'total' => $taxes->total,
           ...
        ]
      ]);
   });