MVC Advice

Published 1 week ago by inkarnation

Hi all, I'm currently trying to develop a new application. Let me just put some context here: On my View, I have a jQuery Datatable showing e.g. Invoices which should load the data using Ajax. For the views etc. I've a Controller called InvoiceController which handle the usual procedures like store(), index(), .. . Now for the datatable I've to create a new action, which will return the data as json back. Since there will be multiple datatables on the application (for different models; assume invoices & clients as of now) I'm not sure what's the recommended way to setup this "controllers". I thought about following approaches:

  • Just create an additional action inside each Controller (InvoiceController, ClientController) which will return the data in correct format
  • Create a dedicated "DatatableController" which will handle all actions for all datatables. The route will then take care about proper url like /client/list -> DataTableController while /client -> ClientController

Any other advice or which approach would be recommended? Many thanks.

Best Answer (As Selected By inkarnation)
tykus

You have the option to check for a request()->wantsJson() condition within the existing Controller method and handle that differently.

You also could create namespaced Controllers, e.g. App\Http\Controllers\Api specifically for the AJAX requests; you would need to be careful that you are not duplicating a bunch of logic between the original Controller method and the API one.

tykus
tykus
1 week ago (305,330 XP)

You have the option to check for a request()->wantsJson() condition within the existing Controller method and handle that differently.

You also could create namespaced Controllers, e.g. App\Http\Controllers\Api specifically for the AJAX requests; you would need to be careful that you are not duplicating a bunch of logic between the original Controller method and the API one.

inkarnation

I like the idea of having the Controller/Action behave differently based on the HTTP Accept Header. Anyway I'm not sure if this is the recommended way to have the same action handling two different kind of requests.

About the namespaced Controllers, I think it would make sense to integrate a new layer behind the Controller (like a Service) which would handle the "business logic" (Means, preparing the request, validating it, fetching data/process actions and pass it back) while the Controller itself just prepares the stuff for the service/client (Converting to proper data structure, .. whatever). Do you think that would make sense?

Anyway I'm currently in favour of your first option...

tykus
tykus
1 week ago (305,330 XP)

It's very much down to your preference - for me, if it is a very simple use case, I would keep it simple and use wantsJson() to determine how to respond. However, it rarely stays very simple!!! By very simple, I mean the only code inside the if block is the json() response which returns a transformed version of the collection, e.g.

public function index()
{
    $things = Model::with()->where()->orderBy()->get();
    // possible other business logic

    if (request()->wantsJson()) {
        return response()->json(transform($things));
    }

    return view('things.index', compact($things));
    
}

If you use the separately namespaced controllers approach, definitely extract the business logic if it will be common to both.

phpMick
phpMick
1 week ago (35,500 XP)

I have a Datatable controller, then all my other controllers which need a Datatable extend it.

inkarnation

@phpMick May you explain better which functionality your Datatable Controller comes with? Is it just providing a functionality like "returnTransformedDataStructure($modelList)" which puts the data into the correct format?

Please let me know!

Cheers

Sign In or create a forum account to participate in this discussion.