1

我将 laravel 资源用于我的 api 响应并添加了分页方法。使用分页方法时,我总是得到这样的结果,其中 laravel 默认提供三个键,即“数据”、“链接”和“元”。但我想根据自己的需要更改资源。

{
"data": [
    {
        "id": 1,
        "name": "Eladio Schroeder Sr.",
        "email": "therese28@example.com",
    },
    {
        "id": 2,
        "name": "Liliana Mayert",
        "email": "evandervort@example.com",
    }
],
"links":{
    "first": "http://example.com/pagination?page=1",
    "last": "http://example.com/pagination?page=1",
    "prev": null,
    "next": null
},
"meta":{
    "current_page": 1,
    "from": 1,
    "last_page": 1,
    "path": "http://example.com/pagination",
    "per_page": 15,
    "to": 10,
    "total": 10
}

}

但我想要这样的结果

{
"data": [
    {
        "id": 1,
        "name": "Eladio Schroeder Sr.",
        "email": "therese28@example.com",
    },
    {
        "id": 2,
        "name": "Liliana Mayert",
        "email": "evandervort@example.com",
    }
],
"metadata": {
    "pagination": {
        "offset": 50,
        "limit": 25,
        "previousOffset": 25,
        "nextOffset": 75,
        "currentPage": 3,
        "pageCount": 40,
        "totalCount": 1000
    }
}

}

我怎么能做到这一点。我正在使用 Laravel 7.*

我的控制器代码:

public function index(Request $request)
{
    return DiscussionResource::collection($this->discussion->getDiscussionList($request));
}

我的模型方法如下所示:

public function getDiscussionList($request){
    return $this->ofSearch($request)
        ->orderBy('created_at', config('settings.pagination.order_by'))
        ->paginate(config('settings.pagination.per_page'));
}

我的资源如下所示:

class DiscussionResource extends JsonResource
{
/**
 * Transform the resource into an array.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
public function toArray($request)
{
    return [
        'id' => $this->id,
        'question_id' => $this->question_id,
        'user_id' => $this->user_id,
        'user_image' => $this->user->userProfile->image,
        'user_role' => $this->user->type,
        'comment' => $this->comment,
        'is_pinned' => $this->is_pinned,
        'created_at' => $this->created_at->toDateString()
    ];
}

}

4

2 回答 2

2

在 laravel 中有很多方法可以做到这一点,这里有两种方法:

第一种方式:您可以创建自定义PaginatedResourceResponse并覆盖默认的paginationLinks. 例如如下:

use Illuminate\Http\Resources\Json\PaginatedResourceResponse;

class CustomPaginatedResourceResponse extends PaginatedResourceResponse
{
    protected function paginationLinks($paginated)
    {
        return [
            'prev' => $paginated['prev_page_url'] ?? null,
            'next' => $paginated['next_page_url'] ?? null,
        ];
    }

    protected function meta($paginated)
    {
        $metaData = parent::meta($paginated);
        return [
            'current_page' => $metaData['current_page'] ?? null,
            'total_items' => $metaData['total'] ?? null,
            'per_page' => $metaData['per_page'] ?? null,
            'total_pages' => $metaData['total'] ?? null,
        ];
    }
}

然后覆盖toResponse方法(实际上,该toResponse方法将资源集合转换为响应)

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

如果您想进一步自定义您的响应,您可以考虑覆盖其他方法。

第二种方式:您可以覆盖中的toResponse方法ResourceCollection并按照您的意愿进行操作!

更多方法在这里!

于 2021-05-31T17:26:19.883 回答
1

如果你想自定义元数据,你可以with()借助 laravel 自带的收藏方法。

// in DiscussionResource file
public function with($request)
{
   return [
      'meta' => [
          'key' => 'value',
       ],
   ];
}

如果你想从控制器自定义它,你可以做这样的事情

return (DiscussionResource::collection($this->discussion->getDiscussionList($request)))
                ->additional(['meta' => [
                    'key' => 'value',
                ]]);

如果您想要它用于单个资源,您可以在toArray()方法中修改它

public function toArray($request)
{
    return [
        'data' => $this->collection,
        'links' => [
            'self' => 'link-value',
        ],
    ];
}

有关更多详细信息,您可以查看https://laravel.com/docs/7.x/eloquent-resources#adding-meta-data

于 2021-05-31T17:39:03.637 回答