如何更改分页响应?

问题描述 投票:0回答:3

在 Laravel 中,无法替换分页响应的默认结构。这是我想要实现的结构:

return response()->json([
    'data' => $items->items()
    'meta' => [
        'current_page'   =>   $items->currentPage(),
        'from'           =>   $items->firstItem(),
        'last_page'      =>   $items->lastPage(),
        'per_page'       =>   $items->perPage(),
        'to'             =>   $items->lastItem(),
        'total'          =>   $items->total(),
    ];
]);
php laravel lumen
3个回答
1
投票

我之前已经通过资源收集解决了这个问题。 Laravel 不支持开箱即用,因此需要做一些工作。

首先,您必须重写

App\Http\Resources\PaginatedResourceResponse
类,这是呈现分页响应的默认方式。然后您可以覆盖返回的分页数据的默认结构。

class CustomPaginatedResourceResponse extends PaginatedResourceResponse
{
}

然后请创建一个使用自定义分页资源的资源集合。

class ItemsResource extends ResourceCollection
{
    public function toArray($request)
    {
    }

    // Override the toResponse method.
    public function toResponse($request)
    {
        return $this->resource instanceof AbstractPaginator
            ? (new CustomPaginatedResourceResponse($this))->toResponse($request)
            : parent::toResponse($request);
    }
}

最后,您只需使用控制器中的

ItemsResource
即可。

return new ItemsResource($items);

这需要了解api资源和源码。请花一些时间阅读 docs 并弄清楚

App\Http\Resources\PaginatedResourceResponse
是如何使用的。


0
投票

在 Laravel 10 中(不确定从哪个版本开始),您可以在

paginationInformation
Laravel 文档
)上实现方法 ResourceCollection,您可以在其中调整分页数据的默认格式。我这样上课:

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class PaginatedJsonResourceCollection extends AnonymousResourceCollection
{
    /**
     * Adjust pagination data format
     *
     * @param Request $request
     * @param array $paginated
     * @param array $default
     * @return array
     */
    public function paginationInformation(Request $request, array $paginated, array $default)
    {
        unset($default['links']);
        $default['meta'] = [
            'page' => $default['meta']['current_page'],
            'lastPage' => $default['meta']['last_page'],
            'perPage' => $default['meta']['per_page'],
            'total' => $default['meta']['total']
        ];

        return $default;
    }
}

如您所见,我从响应中完全删除了

links
属性,并根据我的需要调整了
meta
字段。

然后我需要告诉 Laravel 在创建集合时使用这个自定义类,所以我创建了

PaginatedJsonResource
类:

use Illuminate\Http\Resources\Json\JsonResource;

class PaginatedJsonResource extends JsonResource
{
    /**
     * Create a new resource collection instance.
     *
     * @param  mixed  $resource
     * @return PaginatedJsonResourceCollection
     */
    protected static function newCollection($resource): PaginatedJsonResourceCollection
    {
        return new PaginatedJsonResourceCollection($resource, static::class);
    }
}

然后让我所有的资源扩展这个类:

class ArticleResource extends PaginatedJsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'id' => $this->id,
            'title' => $this->title,
            'content' => $this->content,
        ];
    }
}

现在每当我返回控制器时

return ArticleResource::collection(Article::paginate());

我以自定义格式获取分页数据:

{
  "data": [
    {
      "id": 12345,
      "title": "Article 1",
      "content": "..."
    },
    {
      "id": 12346,
      "title": "Article 2",
      "content": "..."
    },
    ...
  ],
  "meta": {
    "page": 1,
    "lastPage": 50,
    "perPage": 15,
    "total": 1000
  }
}

0
投票

我尝试将

paginationInformation()
直接实现到我的
Resource
中,但它永远不会调用
paginationInformation()
,有什么想法吗?

class SomeResource extends JsonResource
{
    public function toArray(Request $request): array
    {
        //
    }

    public function paginationInformation($request, $paginated, $default)
    {

        dd("called");
    }

}

通过使用调用:

public function index(Request $request, OrderFilter $filters)
{
    return OrderResource::collection(Order::where('x', 'y')->paginate());
}
© www.soinside.com 2019 - 2024. All rights reserved.