Mojolicious在哪里放置内容协商逻辑的最佳位置是什么?

时间:2018-03-17 11:56:40

标签: perl mojolicious

我的Mojolicious申请只能通过jsonhtml回复。

我想在请求不同格式时使用415 Unsupported Media Type状态代码进行回复。

$c->render( text => 'We support only HTML and JSON',  status => 415 )

哪个hook将是放置此逻辑的最佳位置?

UPD

$c->respond_to(
  json => {template => 'hello', data => $data },
  html => {template => 'hello', data => $data },
  any  => {text => 'We support only HTML and JSON', status => 415}
);

hello模板由许多操作呈现。而且我不想在所有操作中copy/paste这段代码片段。我更喜欢:

$c->render( 'hello',  data => $data );

将自动选择hello.json.ephello.html.ep模板中的一个。

我将使用before_routes hook和accepts帮助程序来确定所请求的格式,但不幸的是,每个static文件都会调用它。已经发送静态响应,这将是无用的工作。

那么,使用before_routes挂钩是否可以,或者有更好的地方可以做到这一点?

2 个答案:

答案 0 :(得分:1)

要在处理JSON和HTML后添加响应,请添加any respond_to处理程序。这样,它与所有其他接受/响应处理逻辑位于相同的位置。

$c->respond_to(
  json => {json => {hello => 'world'}},
  html => {template => 'hello', message => 'world'},
  any  => {text => 'We support only HTML and JSON', status => 415}
);

答案 1 :(得分:1)

  

我不想在所有操作中复制/粘贴此代码段。我更喜欢:

$c->render( 'hello', data => $data );
     

将自动选择hello.json.ephello.html.ep模板中的一个。

听起来您可能需要补充$c->render的行为,因为您的控制器及其操作的唯一代码是框架代码。

您可以扩展Mojolicious::Controller创建一个Your::Mojo::Controller模块,其中包含一个专门的render_either(缺少更好的名称)。一般情况下,我会查看render的实施方式,特别是我想在render中解决the following line

my ($output, $format) = $app->renderer->render($self, $args);

$app->rendererMojolicious::Renderer,其文档涉及acceptstemplate_handler

->accepts(..., 'html', 'json')
->template_handler(template => 'foo/bar', format => 'html', ...)

自定义控制器可能如下所示:

package Your::Mojo::Controller;
use Mojo::Base -base;

sub render_either {
    my $self = shift;
    my $template = shift;
    my $args = {@_};

    # Let the renderer know which formats it should accept.
    # Let the renderer know which template to render in which format.
    # Either call $self->render or reproduce its behavior.
}

我见过use Mojo::Base -base;use Mojo::Base 'Mojolicious::Controller;的例子。我不确定选择的含义。