-
Notifications
You must be signed in to change notification settings - Fork 144
Configurable response factory #176
base: 3.x
Are you sure you want to change the base?
Conversation
Hi, Mika. I marked 2 lines for review. If you like this in general, I will finish the PR by providing a documentation entry and a test. Let me know. Thanks! |
4de29f2
to
bf39471
Compare
Sorry it took a while. You already did the correct fix which is to code again That said I have had plan to do something similar. However the factory parameter be a PSR-17 factory and not a callable. If none given it should default to the autodiscovering |
Mika, I have addressed your remark, however while I am writing the documentation entry, I realized a shortcoming with the approach to provide a response factory instance - what if one does not want to create the instance of the factory every time or wants to provide it on demand? In most cases surely the factory is a trivial object with no dependencies, but what if not? One needs to create the instance every time during the initialization, even if it is not used (the check passes and the factory is not needed). You did not like the "callable response factory" approach I implemented originally, how about supporting a "factory provider" use case? To demostrate, compare these: $app = new Slim\App;
// compare this
$app->add(new Tuupola\Middleware\JwtAuthentication([
"secret" => "supersecretkeyyoushouldnotcommittogithub",
"responseFactory" => new MyResponseFactory,
]));
// to the following
$app->add(new Tuupola\Middleware\JwtAuthentication([
"secret" => "supersecretkeyyoushouldnotcommittogithub",
"responseFactory" => function(): ResponseFactoryInterface {
return new MyResponseFactory;
},
])); Quick EDIT: I mean, both cases should be supported not just one of them. |
Mika, I implemented support for the "factory provider", let me know what you think. From my point of view, it does not make sense to crate the response factory every on every request, even if not needed. |
Changed timezones, now I should be available again. I thought about this for a bit. While technically you are technically correct I think the speed penalty is so small it does not warrant the additional complexity of using factory provider instead of factory itself. Also if you are using a custom PSR-17 factory you are probably using the same factory with the framework itself. This means the factory probably has already been instantiated either directly or using a container. |
While I don't really think using a provider brings much more complexity, I agree to go the simpler way. If I wanted to initialize a "heavy" response factory (say class LazyFactory implements Psr17ResponseFactory {
private $original = null;
private $provider;
function __construct(callable $provider){
$this->provider = $provider;
}
function createRequest( ...$args ){
return $this->resolveFactory()->createRequest( ...$args );
}
function resolveFactory(): OriginalFactory {
return $this->original ?? $this->original = call_user_func($this->provider);
}
} And use it as the PSR-17 response factory instead of the original |
3a799b3
to
329edfb
Compare
Does it look OK to you now? Let me write some tests... |
899b4a2
to
de66bb3
Compare
Mika, the test fails, because I need a response factory in order to test the new response factory, but your requirement of |
de66bb3
to
56dcee8
Compare
PSR-17 response factory can be provided in configuration
56dcee8
to
a20be27
Compare
I have updated the test so that it passes with diactoros v1. Should be all good now. |
Yeah, could also just remove the old Diactoros from |
I believe it is needed for the tests. No other response factory is present (besides your meta factory). Anyway the tests pass and tie PR should be ready. Take a look. |
bump. |
bump. Any news? what is missing to approving this issue. The only way that i can see in order to workaround, is making a decorator object. |
Background
This middleware uses
tuupola/http-factory
to create a new response in case an error occurs.The new response is then passed to the
error
callback function.The mentioned http factory detects one of several supported installed PSR-7 libraries and uses one to create the response.
The Issue
After installing a package that consequently installed it's own dependency (
zendframework/zend-diactoros
PSR-7 implementation), which is one of the supported PSR-7 implementationstuupola/http-factory
will detect and use, myerror
callback caused error, because it was expecting a Slim response implementation (Slim\Http\Response
), but got the Zend implementation (Zend\Diactoros\Response
) instead.While this was not a grave issue and was solved by using bare
Psr\Http\Message\ResponseInterface
, there is currently no way around it.The solution
This solution provides a way to pass custom response factory to the middleware, so that one needs not rely on the default
tuupola/http-factory
, but falls back to the default, if no custom one is provided.