Zend_Rest_Route a Zend_Rest_Controller v ZF 1.9

Proč REST a co to obnáší?

V Zend Frameworku 1.9 byla přidána pro používání REST v url a v controlleru.

REST je v módě a proto nám ho přidali i do ZF. Ne vážně samozřejmě každý teď dělá do REST. Implementace RESTu existuje v každém větším frameworku. V ZF už delší dobu je REST klient i server. Klienta můžete využít pro práci s mnohými službami na internetu (twitter, flickr, …).

V tabulce je dobře vidět jak se využije HTTP protokol. Metody PUT, DELETE se běžně nevyužívají.

Akce SQL HTTP
Create Insert PUT
Read Select GET
Update Update POST
Delete Delete DELETE

REST API je součástí mnoha z nich. Pokud máte aplikaci RESTful, není problém potom provozovat i REST api.

  • do ZF byli přidány dvě nové třídy Zend_Rest_Route, Zend_Rest_Controller
  • přinese nám to využití HTTP protokolu (GET, POST, PUT, DELETE)
  • pro používání RESTu změníme controller, budeme používat Zend_Rest_Controller místo Zend_Action_Controller
  • v controlleru je potřeba potřeba definovat tyto metody
    • indexAction()
    • getAction()
    • postAction()
    • putAction()
    • deleteAction()
  • GET je get a všechny destruktivní akce jsou přes POST

Vzal jsem základní tutorial z akrabatu a modifikoval jsem ho pro použití s REST. Zdrojové kódy jsou k dispozici na bitbucketu.

Do bootstrapu je potřeba přidat definici pro Zend_Rest_Route

    function _initRestRoute()
    {
        $this->bootstrap('Request');
        $front = $this->getResource('FrontController');
        $restRoute = new Zend_Rest_Route($front, array(), array(
            'default' => array('albums')
                ));
        $front->getRouter()->addRoute('rest', $restRoute);
    }

    function _initRequest()
    {
        $this->bootstrap('FrontController');
        $front = $this->getResource('FrontController');
        $request = $front->getRequest();
        if (null === $front->getRequest()) {
            $request = new Zend_Controller_Request_Http();
            $front->setRequest($request);
        }
        return $request;
    }

a je potřeba modifikovat controller, aby využíval celký HTTP protokol.

class AlbumsController extends Zend_Rest_Controller
{
    private $_albums;
    private $_form;


    public function init()
    {
        /* Initialize action controller here */
        $this->_albums = new Zend_Db_Table('albums');
        $this->_form = new Form_Album();
    }

    public function indexAction()
    {
        $this->view->title = "My Albums";
        $this->view->headTitle($this->view->title, 'PREPEND');
        $this->view->albums = $this->_albums->fetchAll();
    }

    public function listAction()
    {
        $this->_forward('index');
    }

    public function getAction()
    {
        $this->view->album = $this->_albums->find($this->_getParam('id'))->current();
    }


    public function putAction()
    {
        $album = $this->_albums->find($this->_getParam('id'))->current();
        if ($this->_form->isValid($this->_request->getParams())) {
            $album->setFromArray($this->_form->getValues())->save();
            $this->_redirect('albums');
        } else {
            $this->view->album = $album;
            $this->view->form = $this->_form;
            $this->render('edit');
        }
            
    }

    public function postAction()        
    { 
        if ($this->_form->isValid($this->_request->getParams())) {
           $this->_albums->createRow($this->_form->getValues())->save();
           $this->_redirect('albums');
        } else {
            $this->view->form = $this->_form;
            $this->view->title = "Add new album";
           $this->render('new');
        }

    }


    public function newAction()
    {
        $this->view->title = "Add new album";
        $this->view->headTitle($this->view->title, 'PREPEND');

        $this->view->form = $this->_form;
        
    }

    public function editAction()
    {
        $this->view->title = "Edit album";
        $this->view->headTitle($this->view->title, 'PREPEND');
        $album = $this->_albums->find($this->_getParam('edit'))->current();
        if ($album) {
            $this->_form->populate($album->toArray()); 
        }   
        $this->view->form = $this->_form;
        $this->view->album = $album;

    }

    public function deleteAction()
    {
        $this->view->title = "Delete album";
        $this->view->headTitle($this->view->title, 'PREPEND');
        
        $album = $this->_albums->find($this->_getParam('id'))->current();
        $album->delete();
        $this->_redirect('albums');
    
    }
}