Back in 2017, Adam Wathan made a great talk at Laracon called CRUDdy By Design, which has been recommended and reshared online for years. I decided to summarize it in text form, so instead of watching all 40 minutes, you could read this quicker, also with more examples and my own opinion.
First, I do recommend watching the full video anyway, embedded below.
Let's consider this article just a "compact summary", but if you want the full version with details, those 40 minutes are still worth it.
And before you ask: yes, that video is from 2017. And yes, it's still hugely relevant, despite some small syntax changes.
The Main Point: Everything is CRUD
Let's get straight to the primary point of Adam's talk.
Instead of creating custom non-resourceful methods in Controllers, you should create separate new Controllers with resourceful methods.
A typical example would be a PodcastController
which has typical methods like index()
, store()
, and others, and you want to add a new method subscribe()
.
The problem with the subscribe()
method is that it is a custom action: with adding those, such Controllers may soon grow too big and get hard to read/maintain.
Instead, according to Adam, you should create a SubscriptionController
or PodcastSubscriptionController
with the method store()
.
If we limit each Controller to only CRUDdy methods, it's easier to maintain.
CRUDdy methods are the same ones from Route::resource()
in Resource Controllers:
- index()
- create()
- store()
- show()
- edit()
- update()
- destroy()
In other words, if you want to create a method that is not in the list above, there's a chance of better creating a new separate Controller with one of those methods above, thinking about which of those 7 methods fits best.
Or, even shorter, every Controller should be a Resource Controller.
Repeating the same thing in Adam's words: Never Write Custom Actions.
Three Examples From Adam's Talk
Notice: I will be rephrasing/summarizing examples a bit, and will not go 100% with the video.
Example 1. Nested Resource Controllers
Let's take a look at this example:
1class PodcastController extends Controller { 2 public function index() { /* ... */ } 3 4 public function create() { /* ... */ } 5 6 // ... 7 8 public function listEpisodes($id) { 9 // list episodes of a specific podcast10 }11}
Then, in the Routes...