【问题标题】:Zend-framework controller containing both HTML interfaces and REST interfacesZend 框架控制器包含 HTML 接口和 REST 接口
【发布时间】:2013-04-15 14:43:37
【问题描述】:

我正在使用 Zend 框架开发一个 Web 应用程序。我正在寻找一种智能解决方案,将 RESTful 接口和非 RESTful 接口实现到单个控制器中。

假设我们正在开发一个管理大量纸质杂志信息的 Web 应用程序。首先,我希望我的网站通过访问以下路径来显示所有已注册的杂志,格式为 HTML。

GET /magazine/

另外,我想要一个 HTML 表单来修改新的/现有的杂志信息

GET /magazine/modify/new
GET /magazine/modify/3  (HTML form filled with magazine information where ID=3)

并通过按“提交”按钮添加|更新,这会隐式调用以下路径

POST /magazine/modify

...并重定向到 /magazine/。最后,我想要一个支持 JSON 格式的 HEAD/GET/POST/PUT/DELETE 杂志信息的 RESTful 接口,如下所示。

HEAD /magazine/rest
GET /magazine/rest    (All magazine information in list)
GET /magazine/rest/3  (One single magazine information where ID=3)
POST /magazine/rest
PUT /magazine/rest/new
PUT /magazine/rest/3
DELETE /magazine/rest/3

我唯一的想法是在一个派生 Zend_Controller_Action 的控制器类中准备所有动作。

class SlipController extends Zend_Controller_Action{
    public function init(){}

    public function indexAction(){
        /* Load all magazine information from model and show. */
        $magazine_mapper = new Application_Model_MagazineMapper();
        $this->view->magazines = $magazine_mapper->fetchAll();
    }

    public function modifyAction(){
        $request = $this->getRequest();
        $form = new Application_Form_Magazine();
        if($request->isPost()){
            if($form->isValid($request->getPost())){
                /* Modify magazine information. */
                $modified_magazine = new Application_Model_Magazine($form->getValues());
                $magazine_mapper = new Application_Model_MagazineMapper();
                $magazine_mapper->save($modified_magazine);
                return $this->_helper->redirector('index');
            }
        }else{
            /* Load and prepare form values from Application_Model_Magazine. */
        }
        $this->view->form = $form;
    }

    public function restAction(){
        switch($this->getRequest()->getMethod()){
            case 'HEAD':   /* Do for method HEAD   */ break;
            case 'GET':    /* Do for method GET    */ break;
            case 'POST':   /* Do for method POST   */ break;
            case 'PUT':    /* Do for method PUT    */ break;
            case 'DELETE': /* Do for method DELETE */ break;
        }
    }

问题是这个解决方案让我可以实现每个 REST 操作。我还听说过一个名为 Zend_Rest_Controller 的好类,它(我听说它)使实现 RESTful 接口变得更容易,但是这个类似乎与 Zend_Rest_Route 一起使用,所以我不知道在哪里放置非 RESTful 动作以这种方式。

我想知道这种情况下的最佳做法。如果使用路由器黑客或其他一些解决方案使某些事情变得更好,我想知道如何做到这一点。

【问题讨论】:

    标签: php zend-framework rest web-applications


    【解决方案1】:

    为什么坚持把所有东西都放在同一个控制器中?

    GET /magazine/rest/3 对我来说似乎相当落后。 URL 路径应具有递减范围,即从最不具体到最具体。我会改为GET /rest/magazine/3。这将允许您使用modules,一个用于 Web 应用程序,一个用于 REST:

    /application/modules/app/controllers
        MagazineController.php
            indexAction()
            editAction()
            newAction()
    
    /application/modules/rest/controllers
        MagazineController.php
            getAction()
            putAction()
            postAction()
            headAction()
    

    【讨论】:

    • 哦,我从来没有想过使用modules...我会试试看!谢谢!!
    • 仍然,是否有可能让控制器同时提供两者?据我目前了解,Html 和 Rest/Http 控制器之间的唯一区别是它扩展的基类(我希望 Html 基控制器使用视图来“装饰”控制器子类返回的 ViewModel)。
    • 这就是他们执行方式的不同,是的。但是他们提供的服务的差异要大得多,应该在逻辑上分开。也就是说,当然有可能,但如果你将应用程序的所有操作都放在一个巨大的控制器中,那么你就失去了使用 MVC 设计的意义。
    猜你喜欢
    • 2018-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多