Mojolicious 和 Moose 一起玩得好吗?

Do Mojolicious and Moose play well together?

我正在开发 Mojo 应用程序,我希望能够使用一些 Moose 角色让我的生活更轻松。

我在 CPAN 上看到 MojoX::Moose::Controller,它的内部结构非常简单。我没有看到太多关于将 Moose 与 Mojo 一起使用的信息。我应该注意的任何潜在问题还是一帆风顺?

根据我的经验,它们可以很好地协同工作。我已经使用 Moose 成功构建了 Mojolicious 应用程序(Moo 应该也能正常工作。)

Moose 可以扩展基本的 Mojolicious 控制器 class,然后您可以做任何您想做的普通 Moose 事情。这是一个例子:

package MyApp {
    use Moose;
    extends 'Mojolicious';
    with 'MyApp::Role::Whatever';

    sub startup { 
        my $self = shift;
        my $r = $self->routes;
        $r->get('/')->to('foo#default');
    }
}

package MyApp::Foo {
    use Moose;
    extends 'Mojolicious::Controller';

    sub default {
        my $self = shift;
        $self->render( text => "Helloooooo!!" );
    }
}

他们肯定打得很好。我构建了一个在 20 台服务器的集群上运行的 API。这是一个 mojo 应用程序,它还使用 moose 类 来承担多个角色。

我采用的方法是将应用程序正确分层,一直到存储层。在这方面,只有在堆栈的上层才真正需要 mojo。在早期,我创建了一个基于 moose 的请求对象,然后将其压入堆栈。向下,创建一个基于驼鹿的响应对象,该对象将响应传递回堆栈的上层。最后 mojo 接管并处理最终的 json 响应。

我们正在通过堆栈推动大量生产流量,它表现出色。我做的一件事是确保尽可能使用 XS 版本的模块,因为这可以提高堆栈的性能。

自从我最初提出这个问题以来,我们已经将一些 Mojo + Moose 代码投入生产。我将在这里分享一些注意事项。这个答案实际上是由 Florian Ragwitz 写的。我代表他发帖。

Mojolicious 和 Moose 可以一起玩得很好,但必须注意一些事情才能很好地工作,并且有一些注意事项。

Moose 的构造函数用于创建新对象很重要。使用 MooseX::NonMoose 是确保这一点的简单方法。不打电话给驼鹿 在对象构造期间,许多 Moose 特征,例如 BUILDARGSBUILD、 属性类型约束检查,急切的构建器将无法工作。

MooseX::NonMoose也会委托给原来的Mojolicious::Controller 构造函数,它的行为只是祝福构造函数参数 提供到哈希引用中。这可能会导致一些奇怪的结果。

例如:

package MyController;

use Moose;
use MooseX::NonMoose;

extends 'Mojolicious::Controller';

has foo => (init_arg => 'bar');

稍后...

MyController->new(bar => 42) # bless { foo => 42, bar => 42 }, 'MyController'

注意生成的 blessed 哈希引用如何包含键 foobar,而不是您对普通 Moose class 的期望 bar。这个 只要您不打算将对象插槽与 与另一个属性的 init_arg.

同名

对于可以使用的 Moose 扩展也有限制。 Mojo 需要基于哈希的实例,因此您将无法使用 Moose 提供的任何非基于哈希的元实例,例如 MooseX::GlobRefMooseX::ArrayRefMooseX::StrictConstructor 也不行 这个环境,因为 Moose 无法分辨哪些构造函数参数是 旨在由 Mojo 构造函数使用。

总的来说,结合 Mojolicious 和 Moose 在实践中应该会很好地工作,因为 只要您了解这些小注意事项并且可以接受无法使用 某些 Moose 扩展。