stefanbauer's avatar

Reuse controller / Best Practice same logic frontend/backend

Hi,

it is just a smaller architecture question: Let's take as example here Jeffreys lessons. On the one side there will be for eg. a LessenController with index method for showing the lessons. Let's say, he has some backend, where he can see also (in different formatting) some lessons. What would you do? Create another controller like BackendLessonController (which holds mostly the same logic) or would you place it also inside the regular LessonController, but with another method name. So i could imagine i have a LessonController and 2 methods. One for frontend and one for backend. But also in this way, there would be redundant logic.

So, what way would you suggest? Or am i completely wrong with my thinking? :)

0 likes
9 replies
bencounsell's avatar
Level 7

I would have two different controllers — one for displaying the user accessible content and one for administrating the content.

My folder structure often looks like:

  • Controllers
    • Admin
      • LessonsController
    • LessonsController

The Controllers/Admin/LessonsController would have and auth.admin middleware applied, meaning only admins could access that controller.

The Controllers/LessonsController would handle displaying the content on the site, and would have nothing to do with administering content.

I namespace my admin controllers to App\Http\Controllers\Admin and setup a route group, something like:

Route::group(['prefix' => 'admin', 'middleware' => 'auth.admin', 'namespace' => 'Admin'], function ()
{

    // Lessons
    Route::resource('lessons', 'LessonsController');

});

This way all your admin controllers are protected to admin users only, and you keep your admin area logic separate from your “front-end”.

stefanbauer's avatar

Great answer! Until now i do that also in the same way in some other projects, but had never the problem that i have same "content" on different places. But your solution means, that you have for listing the lessons duplicate logic in both controllers, isn't it? At least some logic. Because i think most logic is out of the controller (in Repos, etc.)

bencounsell's avatar

I use repositories, so there's not really any duplicated logic, I just inject the repository in to the controller's constructor and call the method I need :)

stefanbauer's avatar

Sounds great. Then i know now what to do. Also just of interest: I am collecting lots of opinions about structuring laravel app. How do you do it personally? Put all logic in "behavior" folders like "Repositories", "ServiceProviders", "Events" etc. or do you put it into context folders like "Lessons", "Users" and put in there all the other stuff like Repos, Providers, etc. :-)

bencounsell's avatar

The last app I built I used “content folders” like Lessons or Users, and put everything related to it in there (Repositories, Presenters, Events, etc.), but I found it was quite messy as a lot of classes were grouped in one folder.

Now I've switched to have individual folders for "Events" or "Repositories" and then sub folders in there, something like:

  • Events
    • Users
      • UserRegistered
    • Lessons
      • LessonWasFavourited
      • LessonWasWatched
  • Repositories
    • Users
      • DbUserRepoistory
      • UserRepository
3 likes
kazehaya's avatar

@bencounsell Can you help me out how your middleware looks like and do you use a check inside your route just for admin or also for normal users?

Im trying to figure out what to do but im a little bit confused what is the right way for this..

Im hoping you want to help me :)

bencounsell's avatar

@kazehaya I have a roles model and a user_role pivot table and assign appropriate role(s) to each user.

So in my auth.admin middleware I check that the user has the admin role with something like Auth::user()->isAdmin()

I'm using Laravel 5 and created my own role based system, but if you're using Laravel 4 you can use Entrust to add role-based permissions (there might be something similar for L5, I've not checked!).

pmall's avatar

@stefanbauer

But your solution means, that you have for listing the lessons duplicate logic in both controllers, isn't it?

You don't care. Listing the lessons on the website page is not intrinsically the same logic as listing the lessons on the admin page. It is not because they actually do the same thing that they are the same thing. There is many ways listing lesson on the website and listing lesson on the admin panel could differ. It would be overDRYing :)

You must ask yourself, if I change the way I show the lessons on the website do I want it to be changed the same way in the admin panel. I think not.

OverDRYing mistake : Use complex abstraction to use the same logic to display the both. Because, hey, they do the same thing ! But later you need to change something on the admin panel. And it does not fit the complex abstraction. You ends up redoing everything and wasting time.

You have to break it down in smaller parts until you have some "atomic" pieces of logic and dry these.

4 likes

Please or to participate in this conversation.