久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合

站長資訊網
最全最豐富的資訊網站

laravel實現隨著Resource返回自定義分頁信息!

laravel實現隨著Resource返回自定義分頁信息!


最近向 Laravel 框架提交了一個 想法 — 在 PaginatedResourceResponse 中添加一個自定義分頁信息方法的檢測,以便在使用 Resource 類輸出信息時,能夠非常方便地自定義分頁信息。

為什么需要它

我基本上都是在開發 API。早期時候我都是直接返回,但是這種方式有時候會出現一些問題,也不方便維護,加上經常需要添加自定義字段和針對不同端給出不同數據的情況,我后來就一直在使用 Resource 來定義返回的數據。【推薦:laravel視頻教程】

使用 Resource 很方便也能夠讓邏輯清晰。但它有個不好的地方,那就是分頁信息太多了。針對 API 項目而言,大多數情況下,默認輸出的分頁信息里很多字段并不需要,并且由于經常對接的是一些老項目,需要沿用老的數據格式或者做兼容,分頁信息的字段大不相同,沒辦法直接使用默認返回的分頁信息。

我不知道大家是怎么處理類似情況時的分頁信息的,但在此之前,為了能夠達到目的,我通常有兩種做法,一是自定義 Response,在這里面把數據信息進行重新定義,二是將 Resource 相關的類全部自定義一遍。

我對 Laravel 底層并不是很了解,我也不擅長做抽象的框架開發,但是在經歷這些之后,我發現事情能夠變得簡單很多,正如我在 PR 闡述的那樣,如果可以在 src/Illuminate/Http/Resources/Json/PaginatedResourceResponse.php 中組建分頁信息時,能夠使用其對應 Resource 類的組件分頁信息,那不就不需要每次大費周章的進行自定義很多類了嗎。于是我就提交了這個想法給 Laravel 框架。這個提交在一開始并沒有被直接接受,而是在經過 Taylor 調整后被合并,并發布在 v8.73.2。

這是我第一次向 Laravel 貢獻代碼,也是第一次向這么大的代碼庫提交合并請求,雖然沒有被直接采用,但結果足以振奮人心。

使用示例

那么,我來簡單的示例一下如何使用吧。

默認輸出

{       "data": [],     "links": {         "first": "http://cooman.cootab-v4.test/api/favicons?page=1",         "last": "http://cooman.cootab-v4.test/api/favicons?page=1",         "prev": null,         "next": null     },     "meta": {         "current_page": 1,         "from": 1,         "last_page": 1,         "links": [             {                 "url": null,                 "label": "« 上一頁",                 "active": false             },             {                 "url": "http://cooman.cootab-v4.test/api/favicons?page=1",                 "label": "1",                 "active": true             },             {                 "url": null,                 "label": "下一頁 »",                 "active": false             }         ],         "path": "http://cooman.cootab-v4.test/api/favicons",         "per_page": 15,         "to": 5,         "total": 5     }}

這是 Laravel 默認輸出的分頁信息,是不是很多字段,當然這足夠應對很多場景的使用。但有時候也會因此犯難。我們需要一點靈活。

使用 ResourceCollection 類時

我們先來看看底層邏輯吧!

當在控制器返回一個 ResourceCollection 時,最終會調用其 toResponse 方法以響應。那么可以直接找到該方法看看:

   /**      * Create an HTTP response that represents the object.      *      * @param  IlluminateHttpRequest  $request      * @return IlluminateHttpJsonResponse      */     public function toResponse($request)     {         if ($this->resource instanceof AbstractPaginator || $this->resource instanceof AbstractCursorPaginator) {             return $this->preparePaginatedResponse($request);         }          return parent::toResponse($request);     }

看到沒,如果當前資源是個分頁對象時,它就把任務轉向處理分頁響應了。接著看:

    /**      * Create a paginate-aware HTTP response.      *      * @param  IlluminateHttpRequest  $request      * @return IlluminateHttpJsonResponse      */     protected function preparePaginatedResponse($request)     {         if ($this->preserveAllQueryParameters) {             $this->resource->appends($request->query());         } elseif (! is_null($this->queryParameters)) {             $this->resource->appends($this->queryParameters);         }          return (new PaginatedResourceResponse($this))->toResponse($request);     }

噢,它又轉給了 PaginatedResourceResponse ,這是我們最終需要修改的類,由于 toResponse 的內容太長,就不在這里貼出,反正就是在這里開始組建響應的數據,分頁信息當然也是在這里面做的處理,不過它有個獨立的方法。該方法就是 paginationInformation, 這是在提交 PR 前的邏輯:

/**      * Add the pagination information to the response.      *      * @param  IlluminateHttpRequest  $request      * @return array      */     protected function paginationInformation($request)     {         $paginated = $this->resource->resource->toArray();          return [             'links' => $this->paginationLinks($paginated),             'meta' => $this->meta($paginated),         ];     }

如果你細心的話,你應該能夠想到,這里的 $this->resource 其實就是上面的 ResourceCollection 的實例,那么它的 resource 就是我們的列表數據,也就是分頁信息實例。既然如此,那我們為何不能在 ResourceCollection 中進行分頁信息的處理呢?當然可以,但我們需要加點東西,這就是我提交的想法。

合并 PR 之后,它的邏輯是這樣的:

/**      * Add the pagination information to the response.      *      * @param  IlluminateHttpRequest  $request      * @return array      */     protected function paginationInformation($request)     {         $paginated = $this->resource->resource->toArray();          $default = [             'links' => $this->paginationLinks($paginated),             'meta' => $this->meta($paginated),         ];          if (method_exists($this->resource, 'paginationInformation')) {             return $this->resource->paginationInformation($request, $paginated, $default);         }          return $default;     }

很簡單的處理方式,如果對應資源類中有自定義的分頁信息組建方法,那就使用它自己的,目前而言,這確實是個好想法。

于此,如何自定義分頁信息應該很清晰了。那就是在自己相應的 ResourceCollection 類中添加 paginationInformation 方法即可,比如:

public function paginationInformation($request, $paginated, $default): array     {         return [             'page' => $paginated['current_page'],             'per_page' => $paginated['per_page'],             'total' => $paginated['total'],             'total_page' => $paginated['last_page'],         ];     }

這是自定義后的數據輸出情況:

{     "data": [],     "page": 1,     "per_page": 15,     "total": 5,     "total_page": 1}

結果如我所愿。

使用 Resource 類時

我通常只喜歡定義一個 Resource 類來應對單個對象和列表的情況,這里主要關注如何處理列表數據的分頁自定義。

在控制器中,我一般都是這樣使用:

public function Index(){     // ....     return  SomeResource::collection($paginatedData);}

再來看看 collection 方法里做了什么:

   /**      * Create a new anonymous resource collection.      *      * @param  mixed  $resource      * @return IlluminateHttpResourcesJsonAnonymousResourceCollection      */     public static function collection($resource)     {         return tap(new AnonymousResourceCollection($resource, static::class), function ($collection) {             if (property_exists(static::class, 'preserveKeys')) {                 $collection->preserveKeys = (new static([]))->preserveKeys === true;             }         });     }

原來它把數據轉給了 ResourceCollection,那么只需要將這個 AnonymousResourceCollection 做個自定義不就可以了。

總結

這是一個很小優化,但是很有用。

在此之前,如果想要隨著 Resource 返回自定義分頁信息,會比較麻煩,需要自定義很多東西,這樣的方式,對老用戶而言小菜一碟,但是對新手就可能是件棘手的問題。那么自此之后,無論是老用戶還是新手這件事將變得易如反掌。只需要在對應的 ResourceCollection 類中添加 paginationInformation 方法,類似下面這樣:

public function paginationInformation($request, $paginated, $default): array     {         return [             'page' => $paginated['current_page'],             'per_page' => $paginated['per_page'],             'total' => $paginated['total'],             'total_page' => $paginated['last_page'],         ];     }

不過,如果你使用的是 Resource::collection($pageData) 方式,那么還需要額外自定義一個 ResourceCollection 類,并重寫對應 Resource 類的 collection 方法。

我通常會定義一個對應的基類,然后其它的都繼承它。也可以做個 trait,然后共用。

最后

其實,這個想法我很早就想提交的,但是我一直比較猶豫,這到底是不是一個很大眾的需求。不過我最后想明白了,這樣做既然能為我節省大量重復且危險的工作,有那么多的開發者,總會有人需要的,所以我提交了,同時也是驗證下我的想法到底是否可行,我的做法是否最優,結果當然是我學到了很多,比如寫稍微復雜的測試用例。

另外,我想知道大家有沒其它方法,或你們是怎么對待不同情況的分頁信息的。

最后的最后,你如果也有好的想法,那么盡快提交吧!

贊(0)
分享到: 更多 (0)
?
網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
久久精品五月,日韩不卡视频在线观看,国产精品videossex久久发布 ,久久av综合
天堂日韩电影| 国产视频一区三区| 尤物精品在线| 亚洲一区不卡| 国产精品分类| 理论片午夜视频在线观看| 日韩久久电影| 国产一区91| 久久国产精品免费一区二区三区| 国产精品午夜一区二区三区| 国产 日韩 欧美 综合 一区| 欧美日韩国产传媒| 日韩超碰人人爽人人做人人添| 视频一区欧美精品| 国产精品一区亚洲| 日韩欧美一区二区三区免费观看| 91久久久精品国产| 国产日韩欧美在线播放不卡| 99精品在线观看| 日韩国产在线不卡视频| 日韩免费在线| 日本不卡在线视频| 日本少妇一区| 水蜜桃精品av一区二区| 欧美黄色一区二区| 电影91久久久| 欧美在线综合| 国产精品a级| 国产欧美日韩精品高清二区综合区 | 国产日产一区| 特黄毛片在线观看| 蜜桃视频一区二区三区在线观看 | 亚洲一区二区动漫| 国产精品久久久网站| 美女网站一区| 国产精品v亚洲精品v日韩精品| 久久精品一区二区不卡| 五月国产精品| 国产综合激情| 精品美女在线视频| 日韩专区欧美专区| 中文av在线全新| 日本亚洲三级在线| 久久久精品网| 麻豆精品在线| 久久av一区二区三区| 久久男人av资源站| 国产精品毛片| 91亚洲国产| 久久99性xxx老妇胖精品| 亚洲少妇诱惑| 久久久影院免费| 久久午夜影院| 国产激情精品一区二区三区| 中文字幕日韩亚洲| 亚洲午夜视频| 国产99在线| 国产无遮挡裸体免费久久| 国产视频久久| 91精品国产福利在线观看麻豆| 国产精品尤物| 国产欧美亚洲一区| 日韩专区欧美专区| 久久一二三区| 亚洲色图国产| 亚洲人成高清| 日韩精品视频在线看| 亚洲精品成人一区| 日本不卡一区二区三区| 国产日韩亚洲欧美精品| 国产日韩欧美| 另类综合日韩欧美亚洲| 国产精品久久久久久久久久10秀 | 国产伦精品一区二区三区在线播放| 日韩精品一卡二卡三卡四卡无卡| 红桃视频亚洲| 亚洲乱亚洲高清| 欧美一区91| 国产一区二区精品久| 激情视频网站在线播放色| 国产专区一区| 日韩不卡一区二区三区| 欧美一区二区三区久久精品| 欧美一级久久| 欧美激情一区| 999久久久免费精品国产| 久久精品123| 石原莉奈一区二区三区在线观看| 日韩午夜视频在线| 国产高清日韩| 亚洲午夜黄色| 亚洲精品日本| zzzwww在线看片免费| 精品中文一区| 国产日韩欧美中文在线| 一本大道色婷婷在线| 每日更新成人在线视频| 久久不见久久见免费视频7 | 99久久夜色精品国产亚洲狼| 国产精品毛片一区二区三区| 久久精品资源| 91久久亚洲| 国产精品夜夜夜| 九九综合在线| 欧美亚洲免费| 午夜精品网站| 国产一区二区三区不卡视频网站| 三级亚洲高清视频| 99国产精品免费视频观看| 亚洲精品美女91| 婷婷丁香综合| 精品视频久久| 日韩精品福利一区二区三区| 91精品一区二区三区综合| 免费欧美日韩| 久久精品卡一| 久久久久欧美精品| 国产传媒在线观看| 久久av网站| 日韩和欧美一区二区| 激情91久久| 国产尤物精品| se01亚洲视频| 日韩在线免费| 日韩在线综合| 伊人网在线播放| 性欧美videohd高精| 国产一区二区三区成人欧美日韩在线观看| 国产乱码精品一区二区三区四区 | 午夜欧美巨大性欧美巨大| 精品一二三区| 国产中文欧美日韩在线| 久久精品福利| 美腿丝袜亚洲一区| 麻豆精品在线视频| 麻豆精品在线| 麻豆国产欧美日韩综合精品二区| 日韩三区四区| 久久狠狠久久| 国产精品扒开腿做爽爽爽软件| 日韩av电影一区| 欧美亚洲人成在线| 久久av偷拍| 久久婷婷久久| 水野朝阳av一区二区三区| 中文字幕亚洲精品乱码| 国产情侣一区| 国产美女高潮在线观看| 久久国产电影| 久久国产成人| 久久99精品久久久野外观看| 国产一区二区三区探花| 欧美a级一区二区| 天堂资源在线亚洲| 中文字幕亚洲影视| 国产成人久久精品一区二区三区| 日本精品影院| 亚洲精品无播放器在线播放| 精品中国亚洲| 国产精品人人爽人人做我的可爱| 欧美日韩网址| 成人日韩在线观看| 日韩黄色av| 亚洲国产综合在线看不卡| 日本午夜精品视频在线观看| 不卡福利视频| 日韩av影院| 久久久久久久久久久妇女 | 7m精品国产导航在线| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 天海翼精品一区二区三区| 四虎成人av| 日本va欧美va精品发布| 亚洲免费观看| 黑人精品一区| 麻豆高清免费国产一区| 蜜桃视频一区二区| 国产一区清纯| 蜜桃av在线播放| 国产欧美亚洲一区| 亚洲精品成a人ⅴ香蕉片| 免费视频国产一区| 精品免费av一区二区三区| 香蕉视频成人在线观看| 色一区二区三区| 麻豆久久一区二区| 国产精品一区二区av交换| 日韩精品一二三| 国产视频久久| 亚洲一区激情| 91成人精品| 久久网站免费观看| 新版的欧美在线视频| 国产一区二区三区黄网站| 美女精品久久| 精品高清久久| 红杏一区二区三区| 亚洲最新无码中文字幕久久| 老司机免费视频一区二区| 麻豆视频一区二区|