Monday, 15 March 2010

rest - zf2 restful not reach update method -



rest - zf2 restful not reach update method -

i made restful controller if send id method receives it. when update form expect update method process cant right config , after 1 day issue decided right downwards here.

here code involved route in module config:

'activities' => array( 'type' => 'segment', 'options' => array( 'route' => '/activities[/:id][/:action][.:formatter]', 'defaults' => array( 'controller' => 'activities' ), 'constraints' => array( 'formatter' => '[a-za-z0-9_-]*', 'id' => '[0-9_-]*' ), ), ),

head of controller:

namespace clock\controller; utilize zend\mvc\controller\abstractrestfulcontroller; utilize zend\mvc\mvcevent; utilize zend\view\model\viewmodel; utilize zend\form\annotation\annotationbuilder; utilize zend\form; utilize doctrine\orm\entitymanager; utilize doctrine\orm\entityrepository; utilize clock\entity\activity; utilize \clock\entity\project; wich contains method: public function get($id) { $entity = $this->getrepository()->find($id); $form = $this->buildform(new activity()); #$form->setattribute('action', $this->url()->fromroute("activities", array('action' => 'update'))); $form->setattribute('action', "/activities/$id/update"); $form->bind($entity); homecoming array( "activities" => $entity, "form" => $form ); }

that feeds view:

<h3>edit activity</h3> <div> <?php echo $this->form()->opentag($form);?> <?php echo $this->formselect($form->get("project"));?><br> <?php echo $this->forminput($form->get("duration"));?><br> <?php echo $this->forminput($form->get("description"));?><br> <input type="submit" value="save changes" /> <?php echo $this->form()->closetag($form);?> </div>

after sending it, expect update method in activities take control, get:

a 404 error occurred page not found. requested controller unable dispatch request. controller: activities

edit:@drbeza get, think (not master in routes) right:

zend\mvc\router\http\routematch object ( [length:protected] => 21 [params:protected] => array ( [controller] => activities [id] => 30 [action] => update ) [matchedroutename:protected] => activities )

--

that's it. help?

quick fix

the routematch object tries dispatch activitiescontroller::updateaction have defined activitiescontroller::update that's due using restful controller. controller::update-method tied put-requests. need define method handle updates via post-requests.

i suggest define activitiescontroller::updateaction, create clear in docblock meant handle post-update requests , refactor both ::updateaction , ::update share much mutual helper-methods possible fast solution.

common uri structur information

as nice info have when start developing restful applications/apis: ruby community suggests next url-structure resources:

# these restful /resource (lists) | post (creates) /resource/:id set (updates) | delete (deletes) # these helpers, not restful, , may take post too. /resource/new (shows create-form), post /resource/:id/edit (shows update-form), post detailed problem analysis

a restful update sent consumer via put, browsers sending html-forms may send get or post requests. should never utilize get create something. have utilize post in forms-context.

looking @ problem architectural perspective multitude of possibilities emerge, depending on how big application is.

for little application, tight integration (formhandling , api handling in controller) apply best. getting bigger may want split api-controllers (only restful actions) helper-controllers (form, website handling) talk api-controllers being big (multitude of api-users) want have dedicated api servers , dedicated website servers (independent applications!). in case website consume api serverside (thats twitter doing). api servers , website servers still may share libraries (for filtering, utilities). code sample

as educational illustration made an gist show how such controller like in principle. controller a) untested b) not production ready , c) marginally configurable.

for special involvement here 2 excerpts updating:

/* restful method, defined in abstractrestfulcontroller */ public function update($id, $data) { $response = $this->getresponse(); if ( ! $this->getservice()->has($id) ) { homecoming $this->notfoundaction(); } $form = $this->geteditform(); $form->setdata($data); if ( ! $form->isvalid() ) { $response->setstatuscode(self::form_invalid_statuscode); homecoming [ 'errors' => $form->getmessages() ]; } $data = $form->getdata(); // want filtered & validated info form, not raw info request. $status = $this->getservice()->update($id, $data); if ( ! $status ) { $response->setstatuscode(self::serverside_error_statuscode); homecoming [ 'errors' => [self::serverside_error_message] ]; } // if went smooth, homecoming new representation of entity. homecoming $this->get($id); }

and editaction satisfies browser-requests:

public function editaction() { /* * same newaction * differences: * - first fetch info service * - prepopulate form */ $id = $this->params('id', false); $dataexists = $this->getservice()->has($id); if ( ! $dataexists ) { $this->flashmessenger()->adderrormessage("no entity {$id} known"); homecoming $this->notfoundaction(); } $request = $this->getrequest(); $form = $this->geteditform(); $data = $this->getservice()->get($id); if ( ! $request->ispost() ) { $form->populatevalues($data); homecoming ['form' => $form]; } $this->update($id, $request->getpost()->toarray()); $response = $this->getresponse(); if ( ! $response->issuccess() ) { homecoming [ 'form' => $form ]; } $this->flashmessenger()->addsuccessmessage('entity changed successfully'); homecoming $this->redirect()->toroute($this->routeidentifiers['entity-changed']); }

rest zend-framework2

No comments:

Post a Comment