Closed tonydspaniard closed 5 years ago
Hi @tonydspaniard
Sorry, no PSR-15 support out of the box. To get PSR-15 we need to support PSR-7 which fortunately is already supported thanks do zend-diactoros! I could make something at Diactoros
namespace, what you think?
Maybe for the API: Diactoros\middleware(<PSR-15 compliant>)
Suggestions are welcome.
cc @IvanDelsinne some thoughts?
I could make something at Diactoros namespace, what you think?
It would be awesome.
I would love to help with this. I've been wanting to try this library for a while, but unfortunately, middleware is a must for me before I use it. But, here I am!
The only problem is that I have zero functional programming experience. For looking at the code in Diactoros namespace, it looks like it does nothing else than creating new objects. However, middleware requires a middleware chain or pipe: a class that stores the stack of middlewares and it's able to play them one by one. Either that or explicitly wrapping the route function in a middleware function, and do that for each one of the routes. Or I don't have the enough knowledge of functional patterns to come up with an idea. I think the last one is most probable.
If you can guide me in an approach I can tackle this, I'll be really glad to implement it. :)
We should probably go for zend-stratigility + zend-httphandlerrunner to play around with zend-diactoros.
Desirable API:
$request = Diactoros\request();
$pipe = Stratigility\pipeline();
$pipe(MiddlewareInterface);
$pipe(MiddlewareInterface);
$pipe(MiddlewareInterface);
$pipe2 = Stratigility\pipeline('non_default_name');
$pipe2(MiddlewareInterface);
$pipe2(MiddlewareInterface);
$pipe2(MiddlewareInterface);
HttpHandleRunner\emit(Stratigility\handle($request));
HttpHandleRunner\emit(Stratigility\handle($request, 'non_default_name'));
Maybe more concise:
Stratigility\pipe(MiddlewareInterface);
Stratigility\pipe(MiddlewareInterface);
Stratigility\pipe(MiddlewareInterface);
HttpHandleRunner\emit(Stratigility\handle(Diactoros\request()));
With proper use
s it could be very simple and Siler-ish to read:
use function Siler\Diactoros\request;
use function Siler\Stratigility\pipe;
use function Siler\Stratigility\handle;
use function Siler\HttpHandleRunner\emit;
pipe(MiddlewareInterface);
pipe(MiddlewareInterface);
pipe(MiddlewareInterface);
emit(handle(request()));
Different pipe names as second argument:
pipe(MiddlewareInterface);
pipe(MiddlewareInterface);
pipe(MiddlewareInterface, 'debug');
pipe(MiddlewareInterface, 'debug');
pipe(MiddlewareInterface, 'debug');
env('APP_DEBUG') ? emit(handle(request(), 'debug')) : emit(handle(request()));
What you think?
State could be handled internally by Container
, don't worry to be funcional-full...
Hi @mnavarrocarter Saw you didn't forked it yet, so I'll be working on it, hope to have something merged by the weekend ;)
Sorry, I was busy at work today, but all you said sound pretty cool. :)
Question, is Siler's container PSR-11 compliant?
Another interesting thing to be able to achieve, is to pass middleware to routes and route groups. This is how is done, "a la Slim":
<?php
$app->group(function($app) {
$app->get('/users/{id}', SomeHandler::class)->add(AnotherMiddleware::class); // This middleware affects only this route.
})->add(SomeMiddleware::class); // This gets resolved by the container. This middleware affects the whole group.
Since everything is globally accessible, I don't think it would be super hard. :)
Question, is Siler's container PSR-11 compliant?
No, actually it's just a Singleton with an Array
Another interesting thing to be able to achieve, is to pass middleware to routes and route groups.
I think this 'll composable out-of-the-box, since Siler routes already accept a PSR-7 Request Message as argument. I'll be adding this on the example ;)
@mnavarrocarter, just saw that Slim's Middlewares aren't PSR-15 complaint, am I right? Well, if so, its a +1 for Siler over it 😀 But, Slim's advantage is the onion architecture.
Here is it for Siler, the API, for now, looks like:
<?php
declare(strict_types=1);
require_once __DIR__.'/../../../vendor/autoload.php';
use Siler\Route;
use Siler\Diactoros;
use Siler\HttpHandlerRunner;
use Siler\Stratigility;
use Siler\Http\Request;
$userMiddleware = function ($request, $handler) {
$token = Request\get('token');
if (empty($token)) {
return Diactoros\json('no user', 401);
}
$user = "get_user_by_token:$token";
$request = $request->withAttribute('user', $user);
return $handler->handle($request);
};
$homeHandler = function () {
return Diactoros\json('welcome');
};
$adminHandler = function ($request) {
return Diactoros\json(['user' => $request->getAttribute('user')]);
};
$secretHandler = function ($request) {
return Diactoros\json(['user' => $request->getAttribute('user')]);
};
Stratigility\pipe($userMiddleware, 'auth');
$request = Diactoros\request();
$response = Route\match([
Route\get('/', $homeHandler, $request),
Route\get('/admin', Stratigility\process($request, 'auth')($adminHandler), $request),
Route\get('/secret', Stratigility\process($request, 'auth')($secretHandler), $request),
Diactoros\json('not found', 404),
]);
HttpHandlerRunner\sapi_emit($response);
What you think? @tonydspaniard, any thoughts? Almost a year later... sorry.
PS.: already working: https://github.com/leocavalcante/siler/pull/130/files#diff-c40d676d8de9c7e8a6e456540d4a401d
Hi @leocavalcante,
Is it possible to make use of psr-15 middlewares -https://github.com/middlewares/psr15-middlewares ? If so, can you make a brief example?
Highly interesting framework and concepts. Thanks for sharing.