找我请到 掘金 或者 Github本身也维护不过来那么多站点,对不住你们了。php
👇 更新平台多偶尔会漏掉,若是以为文章还行点个
star
防走失。
你所不知道 ❌ 系列一块儿探索未知
好久没写文章了,在新的公司新的遇到了新的伙伴,胖丁哥哥让我看了 laracon 2017 - Adam Wathan
的视频,略微手痒想分享一下本身的东西,这边使用的是 laravel
做为讲解,可是思想却不局限于于 laravel
或者 php
。
呦呦呦呦,这边是差很少的小二先生~~~~laravel
平时咱们写代码的时候常常会写出不少下面这样的路由:git
Route::get('/podcasts', 'PodcastsController@index'); Route::get('/podcasts/create', 'PodcastsController@create'); Route::post('/podcasts', 'PodcastsController@store'); Route::get('/podcasts/{id}', 'PodcastsController@show'); Route::get('/podcasts/{id}/edit', 'PodcastsController@edit'); Route::patch('/podcasts/{id}', 'PodcastsController@update'); Route::delete('/podcasts/{id}', 'PodcastsController@destroy'); Route::post('/podcasts/{id}/update-cover-image', 'PodcastsController@updateCoverImage'); Route::post('/podcasts/{id}/subscribe', 'PodcastsController@subscribe'); Route::post('/podcasts/{id}/unsubscribe', 'PodcastsController@unsubscribe'); Route::post('/podcasts/{id}/publish', 'PodcastsController@publish'); Route::post('/podcasts/{id}/unpublish', 'PodcastsController@unpublish'); Route::get('/episodes', 'EpisodesController@index'); Route::get('/episodes/{id}', 'EpisodesController@show'); Route::get('/episodes/{id}/edit', 'EpisodesController@edit'); Route::patch('/episodes/{id}', 'EpisodesController@update'); Route::get('/podcasts/{id}/episodes', 'PodcastController@indexEpisode'); Route::post('/podcasts/{id}/episodes', 'PodcastController@storeEpisode'); Route::get('/podcasts/{id}/episodes/new', 'PodcastController@createEpisode');
应该很是熟悉这样所谓 嵌套资源
,随着项目的扩大,这样会使得控制器一个个的变得胖起来逻辑开始复杂起来,如今让咱们开始为这差很少的路由作个变身。github
这边进行一个小插曲,对资源总结起来大概就是 7 个标准的 Action :json
在后面的路由列表中,咱们把只带有这 7 种 Action 的路由器都写成 Resource
。后端
在上面的路由中咱们选择一条常见的路由来作变身:微信
GET /podcasts/{id}/episodes
对于这样的一个 URL,若是咱们只想让控制器只拥有 7 个标准的 Action ,咱们应该把它放在哪一个控制器呢?前后端分离
放在 PodcastsController 控制器中吗?那这样就会与控制器中的 Index
Action 冲突了。
放在 EpisodesController 控制器中吗?这样也会与控制器中的 Index
Action 冲突。ide
GET /podcasts/{id}/episodes => Index GET /podcasts/ => Index GET /episodes/ => Index
那咱们须要怎么安放这个处处被人嫌弃的 URL 呢?post
其实咱们能够把 podcasts 和 episodes 合起来当作一种资源,存放在 PodcastEpisodesController
中。
class PodcastEpisodesController extends Controller { public function index($id) { $podcast = Podcast::with('episodes')->findOrFail($id); return response()->json(['podcast' => $podcast]); } }
Route::resource('podcasts', 'PodcastsController'); Route::resource('episodes', 'EpisodesController'); Route::resource('podcasts.episodes', 'PodcastEpisodesController'); Route::post('/podcasts/{id}/update-cover-image', 'PodcastsController@updateCoverImage'); Route::post('/podcasts/{id}/subscribe', 'PodcastsController@subscribe'); Route::post('/podcasts/{id}/unsubscribe', 'PodcastsController@unsubscribe'); Route::post('/podcasts/{id}/publish', 'PodcastsController@publish'); Route::post('/podcasts/{id}/unpublish', 'PodcastsController@unpublish');
按照这个思路来进行路由的变身,咱们将会获得三个控制器:
PodcastsController
拥有 7个标准 Action,5个非标准的 ActionEpisodesController
拥有 4个标准 ActionPodcastEpisodesController
拥有 3个标准 Action虽然经历瘦身后,路由列表已经变得很短了,可是PodcastsController
中还有 5 个非标准的 Action,咱们将继续对这些方法进行瘦身:
POST /podcasts/{id}/update-cover-image
这个 URL 是用来更新 podcasts 的封面图片的,咱们是不能把封面图片也单独当作一种资源呢?显然是能够的,这个资源中包含了一个更新的方法。
class PodcastCoverImageController extends Controller { public function update($id) { $podcast = Auth::user()->podcasts()->findOrFail($id); $podcast->update([ 'cover_path' => request()->file('cover_image')->store('images', 'public') ]); return response()->json(['message' => 'ok']); } }
这个时候新的路由能够写成:
Route::put('/podcasts/{id}/cover-image', 'PodcastCoverImageController@update');
新的路由表能够写为:
Route::resource('podcasts', 'PodcastsController'); Route::resource('episodes', 'EpisodesController'); Route::resource('podcasts.episodes', 'PodcastEpisodesController'); Route::resource('podcasts.cover-image', 'PodcastCoverImageController'); Route::post('/podcasts/{id}/subscribe', 'PodcastsController@subscribe'); Route::post('/podcasts/{id}/unsubscribe', 'PodcastsController@unsubscribe'); Route::post('/podcasts/{id}/publish', 'PodcastsController@publish'); Route::post('/podcasts/{id}/unpublish', 'PodcastsController@unpublish');
刚才咱们讨论的两个问题都是对于普通的表进行操做,可是若是咱们修改和建立的数据在中间表上咱们又该如何呢?
Route::post('/podcasts/{id}/subscribe', 'PodcastsController@subscribe'); Route::post('/podcasts/{id}/unsubscribe', 'PodcastsController@unsubscribe');
这两个路由,分别对 user_podcast
中间表的进行删除数据和建立数据。
其实咱们能够把中间表也看作一种资源,写成 SubscriptionsController
,其中里面包含两个 Action 有 store
和 destroy
。按照这个思路可把剩下的两个控制器写入 PublishedPodcastsController
,也是包含了 store
和 destroy
Action。
通过这么瘦身下来,咱们的路由表变成这个样子:
Route::resource('podcasts', 'PodcastsController'); Route::resource('episodes', 'EpisodesController'); Route::resource('podcasts.episodes', 'SubscriptionsController'); Route::resource('podcasts.cover-image', 'PodcastCoverImageController'); Route::resource('subscriptions', 'SubscriptionsController'); Route::resource('published-podcasts', 'PublishedPodcastsController');
惊喜不惊喜,刺激不刺激,好看很差看,简洁不简洁!!!
其实,咱们能够把 Everything
都看作是资源,对其进行 CURD
的操做,带来的好处也是显而易见,更加轻的控制器,更加进行的分类,更加的 RESTful。
在困惑的城市里总少不了并肩同行的
伙伴
让咱们一块儿成长。
点赞
。小星星
。m353839115
。本文原稿来自 PushMeTop