Zend Expressive - лучший способ внедрить промежуточное ПО

В настоящее время я изучаю Zend Expressive и вижу несколько вариантов доступа к промежуточному программному обеспечению в рамках маршрутов / действий.

В приложении выразительного скелета есть HomePageFactory, куда контейнер внедряется, затем маршрутизатор, шаблонизатор и т. Д. Извлекаются из контейнера, и с их помощью создается новый класс HomePageAction и возвращается.

Например:

class HomePageFactory
{
    public function __invoke(ContainerInterface $container)
    {
        $router   = $container->get(RouterInterface::class);
        $template = ($container->has(TemplateRendererInterface::class))
            ? $container->get(TemplateRendererInterface::class)
            : null;

        return new HomePageAction($router, $template);
    }

Затем мне понадобился флеш-мессенджер и наткнулся на следующее:

class SlimFlashMiddlewareFactory
{
    public function __invoke($container)
    {
        return function ($request, $response, $next) {
            // Start the session whenever we use this!
            session_start();

            return $next(
                $request->withAttribute('flash', new Messages()),
                $response
            );
        };
    }
}

Так что это немного отличается и добавляет промежуточное программное обеспечение к запросу через атрибут. Который затем может быть найден, где это необходимо, например:

$flashMessenger = $request->getAttribute('flash');

Поэтому на самом деле мой вопрос заключается в том, каковы преимущества / недостатки этих двух способов вовлечения FlashMessenger в действие?

Если у меня есть UserService, который занимается извлечением пользователей из базы данных и, следовательно, может понадобиться в нескольких действиях / маршрутах, лучше ли мне изменить HomePageAction & Factory (и любые другие, которые в нем нуждаются) для принятия UserService?

т.е.

class HomePageFactory
    {
        public function __invoke(ContainerInterface $container)
        {
            $router   = $container->get(RouterInterface::class);
            $template = ($container->has(TemplateRendererInterface::class))
                ? $container->get(TemplateRendererInterface::class)
                : null;
            $userService = $container->get(App\UserService::class);

            return new HomePageAction($router, $template, $userService);
        }

Или мне лучше пойти с тем, как работает FlashMessenger (который кажется немного более простым в управлении), и добавить его к запросу через атрибут, чтобы получить доступ к нему таким образом, где это необходимо?

т.е.

$userService = $request->getAttribute('UserService');

Мне интересно, есть ли какие-либо проблемы с производительностью с последним вариантом, хотя я понимаю, что это может быть сделано таким образом только для определенных маршрутов, а не для UserServer, являющегося широким приложением.

У меня есть ощущение (после написания этого вопроса), что на самом деле это Сервис, а не настоящее промежуточное ПО, поэтому мне действительно нужно изменить HomePageAction & Factory и добавить UserService таким образом, а не делать то, что кажется более простым, и использовать атрибут ala FlashMessenger, Но было бы очень удобно, если бы гуру мог помочь прояснить это.

Спасибо заранее.

1 ответ

Решение

Я не знаю о различиях в производительности, так как я не проверял это. Но я думаю, что вопрос, который вы должны задать себе, - что делает класс? Требуется ли оно другим промежуточным программным обеспечением до или после вызова класса Action, или оно требуется только в классе Action или где-то еще в приложении.

В вашем случае UserService может позаботиться о регистрации или обновлении пользователя. Эти вещи будут добавлены в ActionFactory, как вам подсказывает ваша интуиция. Однако для аутентификации было бы иначе, если бы это было сделано с промежуточным программным обеспечением. Во-первых, вам нужен этот класс в вашем промежуточном программном обеспечении аутентификации, который вы можете передать в промежуточное программное обеспечение авторизации с запросом (или, возможно, только передать аутентифицированный пользовательский объект, вот что я делаю).

Поэтому я полагаю, что практическое правило заключается в том, что если что-то необходимо для изменения входящего запроса или исходящего ответа до / после действия, вы передаете его вместе с запросом, в противном случае вводите его в действие с фабрикой.

Если вы начнете передавать все с помощью запроса, будет очень трудно отследить. Я считаю, что гораздо проще внедрить как можно больше в само действие, потому что тогда я легко вижу, что нужно внутри этого класса, и я могу проверить его проще.

Такие вещи, как флеш-мессенджер, сеанс и аутентифицированный пользователь, которого я бы вставил в запрос

Другие вопросы по тегам