What is the one true way to do this?

Joel Clermont (00:00):
Welcome to No Compromises, a peek into the mind of two old web devs who have seen some things. This is Joel.

Aaron Saray (00:07):
And this is Aaron.

Joel Clermont (00:15):
Programmers like rules, we like having one way to do things. But the reality is there are many different ways to attack the tasks that we do day-to-day. So, Aaron, I was thinking, maybe today we could talk through a couple of examples where there isn't necessarily one true way, or there's at least a variety of choices before you. We could share some thoughts on how we approach it, the reasoning behind it. Maybe that'd be useful to other people. What do you think?

Aaron Saray (00:42):
I think that's a great idea that you just came up with there, Joel.

Joel Clermont (00:45):
I'm so spontaneous. All right, the first example I was thinking about is, I'm going to write some new piece of functionality. Like, where am I going to stick this? Specifically thinking about the action in the Laravel world, the controller action. Where am I going to put that? We could put it in its own controller, right? There's single controllers, or single-action controllers. I could wedge it into the resourceful controller model, or I could take one of my controllers that already has like 30 methods on it and just put one more on it.

Aaron Saray (01:24):
What might be an example of a single-action controller?

Joel Clermont (01:30):
How I would do it?

Aaron Saray (01:31):
Yeah.

Joel Clermont (01:33):
Well, okay. I'll share my opinion even though I was trying to ask you yours. But I personally lean towards the resourceful controllers. To answer your specific question-

Aaron Saray (01:46):
I feel like you're not answering the question.

Joel Clermont (01:48):
I'm getting to it.

Aaron Saray (01:49):
All right.

Joel Clermont (01:51):
I would reach for a single-action controller, when it just didn't make sense to fit in one of the resourceful methods. I'll give an example. Let's say you have an application controller you can apply to a job. You can create an application, you can edit it and so forth. But then there's going to be somebody that either approves or declines that application. To me, yeah, I could maybe wedge approve as an edit/update flow, but it really kind of feels like its own separate workflow. I would generally, in that case, break that out and have an approved application controller with a single-action and a decline application controller with a single-action.

Aaron Saray (02:33):
You're saying there's a number of things you might edit on that application? One of them being approved or the status of it, or whatever. But in some cases it might make more sense just to pull out one single thing to kind of match with your domain and say, "This is what I want to do?"

Joel Clermont (02:55):
Right. Or, maybe in this case, the partial example I was thinking of is a workflow thing. One person submits it and a different person has to approve or decline it. It's kind of like two people with two different possible updates for that application.

Aaron Saray (03:10):
That could get really complicated if you're trying to use the same method all the time. Like, does this user have this permission to edit this particular column in this one piece data? Whereas you could pull it out into just a single controller action. But then once you just want to make single controller actions for all of your methods, I want to see a list, I want to see new-

Joel Clermont (03:30):
What I actually do is I create separate applications, all independent microservices for every single one of those. No, I'm joking. But, yes, I think there is a line where... No, that is not the right answer. Because if something really is create/store, or something really is edit, update, or delete or view or index, those are kind of predefined methods that are available. As a developer coming into a project, I appreciate when the previous developer used those existing conventions because I can more easily grasp those and know where to look for things.

Aaron Saray (04:06):
I think one other thing that I consider when I'm deciding whether to use a single action controller or resource controller is, is this, like I mentioned, a domain sort of process? Is this something I would tell my business and they would understand? Versus the data storage. Sometimes as programmers, we get stuck too much on the data objects and the data storage, and we make all of our interfaces based off of that. But a normal user, they don't want to see a screen then with 27 different things to update, they just want one. You can limit that a lot of times in your UI or something like that. But sometimes it just makes sense to pull out a single sort of very common business related thing into its own controller and say, "This is that task and this task only happens in this scenario."

Joel Clermont (04:58):
Yeah.

Aaron Saray (04:58):
But you did mention something interesting about, how do you know how many methods to put on this controller? Was that kind of where you were getting at?

Joel Clermont (05:09):
You mean if you're not following the resourceful controller methodology? Because if you're following that, you should only have seven, max.

Aaron Saray (05:19):
So there's never a situation that you could... I suppose, yeah. Because those other ones that I've added on in the past usually could have been just a single action on a different controller then, yeah.

Joel Clermont (05:31):
Yeah. I mean, everybody's going to have different opinions on this, but from my experience working on projects, I've created plenty of balls of mud with controllers that have 30 methods on them. You have to draw a line somewhere and I don't like making that decision over and over and over. So, why not make the decision one time. Like, "Hey, let's stick with the resourceful controller. When we have to go outside that, we'll use single-action controllers," and my life just got simpler.

Aaron Saray (06:00):
Plus, with having those resourceful controllers, you get a lot of helpers. Like, authorizeResource helper that can apply authorization automatically to each one of those columns using policies and gates.

Joel Clermont (06:14):
Speaking of authorization, Aaron, that makes me think of a second example. Which is, where do you do your authorization? Just to throw out some ideas, I could write a policy and check that as middleware and a route. I could check that policy in my controller's constructor, I could do authorization inside a form request. I could certainly write any authorization logic I want within the actions. How do you decide where to put that sort of stuff in your application?

Aaron Saray (06:44):
I think there's a couple different rules that you can find in the Laravel documentation that kind of indicate, "This is how you might use this." If you have an object that can be hydrated, use the policies. If you have things that are more just action-based, use gates. Stuff like that. But I think the more important rule on something like this is to stay consistent and especially work with your team. I think one of the big things too is also remembering that as developers, we're always learning more, right? Sometimes when you learn the next thing, it's really exciting to go, "I'm going to just switch and do that now."

Joel Clermont (07:24):
Yeah.

Aaron Saray (07:25):
Then you have two separate ways of doing something in your app. Then as you finish doing that second way, then you suddenly have learned another thing and you have three. Or, if you're like us and we're jumping around between different projects, we learn something from each one. How do you not just run to the next new shiny thing? That consistency is super important, even if it's not the newest, brightest, shiniest way of doing something.

Joel Clermont (07:48):
Right. Yeah, it can be almost like an archeological dig. Where you go down through the layers and you'd be like, "Oh, here's where they learned about gates." Because all of a sudden there's a bunch of gates in the commit, but it's not used anywhere else in the older code. Yeah, I agree. Consistency is super important, especially on a team. But I would even say if you're a solo dev, consistency is also going to save your sanity. If you maintain a project long enough, you'll forget why you did things a different way in this one part of the code base. So be even consistent with yourself, makes a lot of sense too.

Aaron Saray (08:22):
Or, if you're a guy like Joel who worked by himself for many years and then got a extremely awesome blessing of having me join with him and suddenly he had to work on a team, it makes it a little bit easier for the person that joins in.

Joel Clermont (08:36):
Fewer skeletons in the closet is always a good thing when you don't know who might look at this in the future. Yes, wise is words of advice.

Aaron Saray (08:50):
So, as been proven many, many times on this podcast, I'm a bit of a weirdo. I like reading the documentation. First word I ever won a Spelling Bee with was dictionary.

Joel Clermont (09:07):
What? Is that a true story?

Aaron Saray (09:10):
Yeah, exactly.

Joel Clermont (09:12):
Okay.

Aaron Saray (09:13):
So I got Word of the Day coming to me from emails. I've been finding a lot of interesting words that I think we've left by the wayside and we don't consider anymore. I think it's time that maybe we bring a couple of these back.

Joel Clermont (09:31):
Okay.

Aaron Saray (09:33):
The first word that I saw the other day, and I actually had to look up, was... Because I thought it was slang, but turns out it's real, is churlish.

Joel Clermont (09:46):
Churlish. Joel is churlish at the beach, no.

Aaron Saray (09:50):
S-H, churlish.

Joel Clermont (09:52):
Churlish, okay.

Aaron Saray (09:53):
Yeah, it's even worse now because I can't seem to say these words. But churlish is like mean-spirited.

Joel Clermont (10:02):
What do you mean?

Aaron Saray (10:03):
What are words that you know that maybe I wouldn't know or listeners wouldn't know that you feel like need to be educated on?

Joel Clermont (10:13):
Well, if you didn't even know churlish, I mean, there's probably lots of words you didn't know. Just the other day, I read before bed, and there was a word that I've seen many times and I kind of knew what it meant, but I finally... I read on a Kindle, so I tapped on it to see what it actually meant. And it was something totally different, but now I can't remember what that word was and I'm not going upstairs to get my Kindle. I guess I'm still a little bit in shock because I know how jealously you guard your inbox, but yet every single day you allow an email with just a word in it to come to your inbox?

Aaron Saray (10:53):
Well, I mean it has a definition too.

Joel Clermont (10:55):
Okay, all right. Sorry if I was being churlish there, I did not mean to.

Aaron Saray (11:00):
Oh.

Joel Clermont (11:01):
Oh. Now I'm going to keep a note by my bedside with words I come across that I don't know what they mean. And I'll get back to you on that.

Aaron Saray (11:13):
Yeah, I think that'll go over really well. You're just in the middle of the night just reading a book, you suddenly go, "Oh," you lean over and start writing something down. Your wife says, "What are you doing?" "I got a word for Aaron."

Joel Clermont (11:25):
The Word of the Day.

Aaron Saray (11:27):
Oh man. I'm going to send him an email.

Joel Clermont (11:31):
Yeah. 1:00 am, churlish.

Aaron Saray (11:36):
Does your team struggle with consistency?

Joel Clermont (11:39):
We can help. Contact us for a free consultation at our website, nocompromises.io.
For those that stuck around to the end, the word I was thinking of is desultory. Now I'm going to make you go look it up. And if you skipped past the closing song, you missed this gem of a word.

No Compromises, LLC