I’m trying to understand why Slim requires the ResponseFactoryInterface, but it doesn’t quite make sense to me.
The ResponseFactoryInterface is actually the only dependency in the App class that isn’t optional. All the other dependencies it has no issue resolving on its own.
Looking in the code the ResponseFactoryInterface is passed all throughout the Slim classes, but there’s only a few places that it seems to be used (correct me if I’m wrong).
A) Passing a Response to a route callable
B) Responding with an empty response in the event of a HEAD request
C) Using the Slim redirect helper
D) Responding to an error
I think the most important one is A, so that it can pass a Response to the route callable. It makes sense that Slim would want the application to work by itself without any other requirements; without the user needing any specific HTTP implementation, and without the user needing a dependency injection container. In this way, Slim in a way acts as a DI container for the ResponseFactory. But if one were to follow the PSR-15 ResponseHandlerInterface, then Slim would just… drop the Response it created. I think following PSR-15 is arguably considered the best practice so when using the best practices Slim shouldn’t need to even create a Response here.
For B, it’s creating a new Response just to replace the existing Response’s body with the new Response’s empty body. I would think that Slim should just empty the existing Response body, but it is true that the body might not be writable. Why doesn’t it just use the StreamFactory to create a new stream? The only reason I can think of is that by using the same ResponseFactory that was used to create the original Response, we can guarantee that the StreamInterface on the Response will be of the same implementation of the existing StreamInterface already on the Response. PSR-7 ResponseInterface implementations shouldn’t be relying on a specific StreamInterface implementation here though anyways, and since this is only happening as a workaround for when the user is violating RFC 2616, it doesn’t seem like a good reason to require the ResponseFactoryInterface inside Slim application.
For C the Redirect functionality is really a helper function / pre-existing route callable and at one point a Route callable will need to return a Response. But, this isn’t necessary functionality of Slim and could be arguably out of the scope of what one would use Slim for. Especially when considering Slim is supposed to be micro. This is the only Slim-defined route callable as well.
And lastly D makes the most sense (or for me is the only place that makes sense) where Slim would want to create a Response object. We want to be able to respond to errors with a fresh Slim installation so Slim should be able to create Responses in these cases. This is one of the few things that Slim does to make it stand out from being just a router. But it too is something that could be or is even likely to be replaced by a full fledged application, one that really uses Slim only as the microframework Slim strives to be.
At its core, Slim is a dispatcher that receives an HTTP request, invokes an appropriate callback routine, and returns an HTTP response. That’s it.
It also defines a redirect route callable and handles exceptions and builds out error responses.
I think all of the instances of where Slim is creating a Response is additional functionality, further than what Slim is intended to be used for. With a properly built application using PSR-15 RequestHandlerInterface implementations, Slim shouldn’t need to create the response at all. It’s really the responsibility of the route callable (or code the route callable relies on, such as a Responder) to create a Response. Yet still the ResponseFactoryInterface is a required dependency of Slim, and even when using the PSR-15 middleware Slim is using it to create a Response.
Should this really be the case? Perhaps there’s some aspect of this I’m not considering, but I would think that one should be able to implement Slim without giving it access to any ResponseFactory. I could understand how it could be something that Slim uses by default for people who want a more full fledged solution than just an HTTP request dispatcher, but for those of us using Slim for just what it claims to be I would think we should be able to instantiate it without giving it any ResponseFactoryInterface. This is why I use Slim, this is all I want Slim to do.
In the end this is probably all pedantic because you can just pass in a ResponseFactoryInterface to the Slim application and still write the application in a way where Slim doesn’t need to use it. But I still would be interested to hear if there’s any other aspects I’m not considering here or if I’m looking at the entire thing in the wrong way.