在控制器层中进行内容协商是否可以?

时间:2012-10-14 11:18:44

标签: php model-view-controller rest zend-framework2 content-negotiation

在Zend Framework 2中,内容协商发生在视图层上,我对它非常满意。我的控制器中的一个例子:

public function viewAction()
{
    $id   = $this->params('id');
    $user = $this->getRepository()->findUser();

    return new ViewModel(array(
        'user' => $user,
    ));
}

这会使view.phtml模板呈现为返回html,或者将用户对象转换为JSON响应。所谓的视图策略决定了如何根据请求呈现响应。

我的网络应用程序中的“REST”应用程序流程

这种类型的内容协商对许多用例非常有用:

  1. /userindexAction()会返回一组users => JSON的html可能;
  2. /user/1viewAction()返回用户对象=>可能的html或JSON(例子来自上面);
  3. /user/1/updateupdateAction()会返回一个html表单。当出现错误时,此URL的POST将返回html或JSON。或者成功后,它会重定向到viewAction(),从而返回用户的新版本=> html和JSON再次成为可能;
  4. /user/createcreateAction()会返回一个html表单。当出现错误时,此URL的POST将返回html或JSON。或者在成功时,它会重定向到viewAction()以获取刚刚创建的用户=>再次使用html和JSON
  5. 我的问题

    在一些用例中,内容协商在控制器层中是“必需的”。我不确定我是否忽略了一些可能性:我可以使用哪些选项,例如以下情况?

    1. 删除用户:POST到/user/1/delete。如果是html视图,您将被重定向到用户列表(现在缺少已删除的用户)。如果你想要一个JSON响应,你想要返回200 OK和一个JSON对象,并带有删除成功的消息。
    2. 对博客文章发表评论。如果是html视图,您将被重定向到您看到附加评论的帖子。如果您要求JSON响应,则需要返回200 OK和带有刚刚放置的注释的JSON对象。
    3. 我的目标是不复制视图层中已存在的内容协商。它也会让我的控制器变得更胖,因为我现在有两个可能的响应(JSON vs html),但这可能不是唯一的情况。如果我以后想要支持XML或其他格式,我会为每个响应类型的操作切换。

1 个答案:

答案 0 :(得分:2)

有趣的是,我们目前正在寻找将视图策略监听器中的内容协商方面转移到控制器插件中。理由基本上就像你注意到的那样 - 控制器的工作是将传入的请求与适当的模型视图相匹配。因此,是的,我认为你的方向正确 - 而现在为2.1开发的工具很可能适合你很好的方法。 (有关详细信息,请参阅https://github.com/zendframework/zf2/pull/2615。)