DEV Community

Dainius
Dainius

Posted on

Respond to multiple content types in Laravel from the same controller

One of the things I really like in rails is respond_to function. In really simple terms, it allows you to reuse the same controller for different content types. For example if the request is AJAX, you can return a JSON response, otherwise, respond with HTML.

I always wanted this functionality in Laravel, but I did not really like most of the implementations I found online. So I have been using simple early returns:

if ($request->wantsJson()) {
    return [
        'success' => true,
    ];
}

return view('users');
Enter fullscreen mode Exit fullscreen mode

This works, but something about it always makes me look for other solutions. Today I decided to give it a try myself and implemented a very simple solution that allows me to write code like this:

Route::get('/', function () {
    return response()
        ->to('html', fn() => view('welcome'))
        ->to('json', fn() => [
            'success' => true,
        ]);
});
Enter fullscreen mode Exit fullscreen mode

The best thing about this (and the main difference to other implementations) is that you can return a closure, meaning that the code will only get called if it matches the requested content type. PHP7.4 makes it even better because we can return an arrow function and we don't need to add use keyword. So for example if we need to use a request or another variable, we can easily do so:

Route::get('/users', function (Request $request) {
    return response()
        ->to('html', fn() => view('users', [
            'users' => User::all(),
            'query' => $request->get('query'),

        ]))
        ->to('json', fn() => [
            'users' => UserResource::collection(User::all()),
        ]);
});
Enter fullscreen mode Exit fullscreen mode

The code for this is quite simple - only around 20 lines. Although it's probably not ready for production use as is, I will be trying this out in my own projects. With some unit tests, I think it would make a really nice composer package. Would this be of interest to anyone? Let me know what do you think 👍

Top comments (1)

Collapse
 
devhammed profile image
Hammed Oyedele • Edited

Please carry on, I will also find time to contribute to it 🙌🙌🙌