Mojolicious中内容协商逻辑及415响应的最佳Hook位置
嘿,我来帮你搞定这个Mojolicious的问题,分两部分说清楚:先落实响应格式限制的代码,再聊聊内容协商逻辑该放哪个Hook最靠谱~
一、实现仅支持HTML/JSON响应的正确姿势
你提到的respond_to用法完全是Mojolicious处理内容协商的标准操作,直接用就对了!给你一个完整的控制器动作示例,一看就懂:
sub hello { my $c = shift; # 假设这是你从业务逻辑里拿到的数据 my $data = {greeting => 'Hey there from Mojolicious!'}; $c->respond_to( json => {template => 'hello', data => $data}, html => {template => 'hello', data => $data}, any => {text => 'We support only HTML and JSON', status => 415} ); }
这样一来,当请求的Accept头是application/json时返回JSON格式,text/html时返回HTML模板渲染的内容,其他任何格式请求都会直接返回415状态码和提示文本,完美匹配你的需求。
二、内容协商逻辑的最佳Hook位置
如果你的整个应用都需要统一做这个格式限制,那around_action Hook绝对是最佳选择。原因很简单:它会包裹每个控制器动作的执行流程,能确保在动作完成业务逻辑后,统一处理内容协商,避免在每个动作里重复写respond_to代码。
给你一个全局配置的例子,直接加到你的应用类(比如lib/MyApp.pm)的startup方法里:
sub startup { my $self = shift; # 先配置你的路由... # 添加全局内容协商Hook $self->hook(around_action => sub { my ($next, $c, $action, $last) = @_; # 先执行控制器动作,让动作把业务数据放到stash里(比如$c->stash(data => $data)) my $result = $next->(); # 统一处理响应格式 $c->respond_to( json => {template => $action, data => $c->stash('data')}, html => {template => $action, data => $c->stash('data')}, any => {text => 'We support only HTML and JSON', status => 415} ); return $result; }); }
这样每个控制器动作只需要专注于业务逻辑,把数据存到stash的data键里就行,不用再写重复的响应处理代码,非常高效。
如果只是部分路由需要这个限制,那没必要搞全局Hook,直接在对应的控制器动作里写respond_to,或者给目标路由组加个前置处理,灵活性更高。
另外提一句,before_render Hook虽然也能介入渲染流程,但它更适合修改渲染参数,而around_action能完整包裹动作执行,对于全局统一控制响应格式来说,是更合适的选择。
内容的提问来源于stack exchange,提问作者Eugen Konkov
相关产品推荐
相关产品推荐

