找我請到 掘金 或者 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