Published July 26, 2017
The new Responsable
interface in Laravel is really awesome, it allows us to simplify our controllers with custom responses objects.
But one of the complexity with responses is the content negotiation and the new feature doesn't help us on this. How could we solve this problem?
The new feature
First, let's look at how Laravel uses the Responsable
interface in the Router.
if {
$response = $response;
}
if {
$response = ;
} elseif {
$response = new ;
} elseif {
$response = new ;
}
The only method on the Respondable
interface is the toResponse
method. Then, if the response is Jsonable
or something similar, Laravel will use the JsonResponse
which json_encode
all the data.
Adding Content Negotiation
There is no sign of Content-Negotiation in this method. So if I need to build a response in JSON or in HTML depending of the type the request, I will have some conditions in my controller:
Not too bad, thanks to the awesome wantsJson()
method, but it could be better (especially if my controller is not a simple database query):
Better! Now let's dive in the UsersResponse
:
Avoiding conditionals with polymorphism
It's often a good thing to replace conditionals by polymorphism. I would rather prefer this response with a new NegociateContent
trait:
Or this one which extends a new BaseResponse
:
The NegociateContent
or the BaseResponse
implementations are really straightforward. We can add more checks and content type if needed of course.
Let's try to build the same view
helper as in mailables
We can even simplify the toHtmlResponse
method with the same concept as in Mailable
. As you may know, in mailables, all public properties are directly accessible in the mail view.
public $users;
I stole this code from the Illuminate\Mail\Mailable
class in the framework (I just refactored it to collections).
Conclusion
I think these few lines of code really improve the Responsable
interface. I really like the Mailable
reflection as it feels really natural to me.
I may try to pull request the framework to add these features if people like them so don't hesitate to send me a message on Twitter @ThibaudDauce or by mail (thibaud@dauce.fr) to tell me what you think!