Open schnittstabil opened 7 years ago
I'm not sure if this is a good idea because I see the use of callable as a feature implementation. For example, I have this middleware dispatcher with some features like support of callables, container-interop, nested middlewares, etc... IMHO, the support of callables is another feature, not special or more important than others, due the ability to instantiate anonimous classes in php7, opening a new way to do the same, but safety (and better). I just use closures when I'm too lazy to respect the psr-15 interface signature :D
I see the use of callable as a feature implementation.
That is exactly its purpose. It allows middleware dispatchers to easily implement a callable
feature, thus they do not need to reinvent the wheel. In addition, consumers of middleware dispatchers which do not provide a callable
feature, can easily reuse their already existing closures.
And more importantly, they do not have to test that feature…
Yes but I mean that you're using a 1:1 convert. This callable works:
$callable = function (ServerRequestInterface $request, DelegateInterface $delegate) {
return $delegate->process($request);
}
but a more lazy typed callable doesn't:
$callable = function ($request, $delegate) {
return $delegate->process($request);
}
And for me, it's more confortable use callables to create lazy middlewares, for testing purposes or for minor operations, because if I need strong typing, I can do this:
$middleware = new class () implements MiddlewareInterface
{
public function (ServerRequestInterface $request, DelegateInterface $delegate) {
return $delegate->process($request);
}
}
That it's faster than callables (because there's no need to create wrappers or use Reflections). Of course, this only works in php7, but I think is the primary focus.
I understand your point of view. But, for example the is_middleware
may look like that:
function is_middleware($var, bool $strict)
{
/* short circuit for interface implementers */
if ($var instanceof MiddlewareInterface) {
return true;
}
if (! is_callable($var)) {
return false;
}
if (! $strict) {
return true;
}
// use reflection
…
}
If we think about middleware frameworks, then I can imagine a usage like this:
class App
{
public function get(string $route, $middleware)
{
$middleware = to_middleware($middleware, $this->debug); // throw an exception in case of non-middleware
…
}
…
}
This means we can type-check early:
$app = new \App([
'debug' => true,
]);
// this uses reflection:
$app->get('/hello/{name}', function (ServerRequestInterface $request, DelegateInterface $delegate) {
…
});
// this doesn't uses reflection:
$app->get('/hello/{name}', new ContactMiddleware());
$app->run();
Well, that all depends on the features a concrete framework wants to provide. If you feel that this does not fit to http://github.com/middlewares, then I will create it at http://github.com/schnittstabil – that wouldn't be a tragedy :wink:
I think this organization should focus mostly in creating psr-15 middleware packages that everybody can consume, instead packages for frameworks or other implementations. For this kind of utilities, we have a middlewares/utils package, so if you like, you can add this feature as a static class. For example:
use Middlewares\Utils\CallableValidator;
$valid = CallableValidator::isMiddleware($callable);
As you can see, there's a CallableMiddleware
, a Dispatcher
and a Delegate
, so you can reuse this classes to create the toDelegate
and toMiddleware
functions.
:+1: middlewares/utils seems the right place to provide such features.
I'm planning to create 4 middleware related projects, allowing clients to additional deal with
callable
middlewares:middleware/is-delegate
middleware/is-middleware
middleware/to-delegate
, casting/adaptingDelegateInterface
instances andcallable
delegates toDelegateInterface
instances.middleware/to-middleware
, casting/adaptingMiddlewareInterface
instances andcallable
delegates toMiddlewareInterface
instances.I'm always shilly shally about project names. For example:
is-delegatable
sounds better, butis-middlewarable
may sounds weird, or doesn't it?@middlewares/contributors Thoughts are welcome.