Consultez la FAQ sur le ZF avant de poster une question
Vous n'êtes pas identifié.
Bonjour,
Je voudrais développer une api de plusieurs services avec la méthode REST mais je ne sais pas vraiment qu'elle est la bonne architecture pour qu'elle soit fiable, robuste et modulable.
J'ai voulu me basé sur cette façon de faire https://github.com/codeinchaos/restful-zend-framework mais je ne sais pas si elle est toujours d'actualité et surtout si elle est correcte.
J'ai vais essayé de vous expliquer ma façon de faire et si ça peut aider d'autre ZENDER'S
- application/boostrap
[lang=php] protected function _initRoutes(){ $frontController = Zend_Controller_Front::getInstance(); $routeur = $frontController->getRouter(); //Add the REST route for the WEBSERVICES module only $restRoute = new Zend_Rest_Route($frontController,array(),array('webservices')); $routeur->addRoute('rest',$restRoute); }
- Création d'un module application/modules/webservices
- application/modules/webservices/bootstrap
[lang=php] class Webservices_Bootstrap extends Zend_Application_Module_Bootstrap{ public function _initAutoload(){ $autoloader = new Zend_Application_Module_Autoloader(array('namespace'=>'Webservices_','basePath'=>APPLICATION_PATH.'/modules/webservices')); return $autoloader; } }
- application/modules/webservices/models/Webservices1.php
[lang=php] class Webservices_Model_Webservices1{ /** * Add method * * @return String */ public function test() { return 'test method called'; } }
- application/modules/webservices/controllers/RestController.php
[lang=php] class Webservices_RestController extends Zend_Rest_Controller{ public function init(){ $this->_helper->layout->disableLayout(); $contextSwitch = $this->_helper->getHelper('contextSwitch'); $contextSwitch->setContext('html',array('suffix'=>'','headers'=>array('Content-Type'=>'text/html;Charset=UTF-8'),'callbacks'=>array())); if(!$contextSwitch->hasContext($this->_getparam('format',''))) $this->_request->setParam('format','xml'); $contextSwitch->addActionContext($this->getRequest()->getActionName(),array('html','json','xml')); $contextSwitch->setDefaultContext('xml'); $contextSwitch->setAutoDisableLayout(true); $contextSwitch->setAutoJsonSerialization(false); $contextSwitch->initContext(); $this->_ws = new Webservices_Model_Webservices1(); } public function headAction(){} public function indexAction(){$this->_forward('get');} public function getAction(){ $this->getResponse()->setHttpResponseCode(200); $resource = strtolower($this->_getParam('resource','')); $existResource = false; switch(true){ case ($existResource=strstr($resource, 'questions')): $this->_forward('questions'); break; case ($existResource=strstr($resource,'responses')): $this->_forward('responses'); break; } if(!$existResource){ $this->getResponse()->setHttpResponseCode(400); $this->view->succes = 'false'; $this->view->error = 'requested resource not found'; $this->view->method = $resource; } } public function responsesAction(){ $this->view->succes = 'true'; $this->view->method = 'responses'; $result = $this->_ws->test(); $this->view->result = array('result'=>$result); } public function questionsAction(){ $this->getResponse()->setHttpResponseCode(200); $this->view->succes = 'true'; $this->view->method = 'question'; $this->view->result = array(); } public function postAction(){ $this->denied(); } public function putAction(){ $this->denied(); } public function deleteAction(){ $this->denied(); } public function denied(){ $this->getResponse()->setHttpResponseCode(403); $this->view->succes = 'false'; $this->view->error = 'Acces denied'; } }
- application/modules/webservices/views/scripts/rest/get.json.phtml & response.json.phtml
[lang=php] $result = array('succes'=>$this->succes,'method'=>$this->method,'result'=>$this->result,'error'=>$this->error); echo Zend_Json::encode($result);
- application/modules/webservices/views/scripts/rest/get.xml.phtml & response.xml.phtml
[lang=php] $serializer = new App_Serializer_Adapter_Xml(); $result = array('succes'=>$this->succes,'method'=>$this->method,'result'=>$this->result,'error'=>$this->error); echo$serializer->serialize($result);
- application/modules/webservices/views/scripts/rest/get.phtml & response.phtml
[lang=php] Zend_Debug::dump($this->succes); Zend_Debug::dump($this->method); Zend_Debug::dump($this->result); Zend_Debug::dump($this->error);
- library/MyApp/Serialiser/Adapter/Xml.php
[lang=php] <?php class App_Serializer_Adapter_Xml extends Zend_Serializer_Adapter_AdapterAbstract { /** * @var array Default options */ protected $_options = array( 'rootNode' => 'response', ); /** * Serialize PHP value to XML * * @param mixed $value * @param array $opts * @return string * @throws Zend_Serializer_Exception on XML encoding exception */ public function serialize($value, array $opts = array()) { $opts = $opts + $this->_options; try { $dom = new DOMDocument('1.0','utf-8'); $root = $dom->appendChild($dom->createElement($opts['rootNode'])); $this->createNodes($dom, $value, $root, false); return $dom->saveXml(); } catch (Exception $e) { require_once 'Zend/Serializer/Exception.php'; throw new Zend_Serializer_Exception('Serialization failed', 0, $e); } } /** * Deserialize XML to PHP value * * @param string $json * @param array $opts * @return mixed */ public function unserialize($xml, array $opts = array()) { try { $json = Zend_Json::fromXml($xml); return (array) Zend_Json::decode($json, Zend_Json::TYPE_OBJECT); } catch (Exception $e) { require_once 'Zend/Serializer/Exception.php'; throw new Zend_Serializer_Exception('Unserialization failed by previous error', 0, $e); } } private function createNodes($dom, $data, &$parent) { switch (gettype($data)) { case 'string': case 'integer': case 'double': $parent->appendChild($dom->createTextNode($data)); break; case 'boolean': switch ($data) { case true: $value = 'true'; break; case false: $value = 'false'; break; } $parent->appendChild($dom->createTextNode($value)); break; case 'object': case 'array': foreach ($data as $key => $value) { if (is_object($value) and $value instanceOf DOMDocument and !empty($value->firstChild)) { $node = $dom->importNode($value->firstChild, true); $parent->appendChild($node); } else { $attributes = null; // SimpleXMLElements can contain key with @attribute as the key name // which indicates an associated array that should be applied to the xml element if (is_object($value) and $value instanceOf SimpleXMLElement) { $attributes = $value->attributes(); $value = (array) $value; } // don't emit @attribute as an element of it's own if ($key[0] !== '@') { if (gettype($value) == 'array' and !is_numeric($key)) { $child = $parent->appendChild($dom->createElement($key)); if ($attributes) { foreach ($attributes as $attrKey => $attrValue) { $child->setAttribute($attrKey, $attrValue); } } $this->createNodes($dom, $value, $child); } else { if (is_numeric($key)) { $key = sprintf('%s', $this->depluralize($parent->tagName)); } $child = $parent->appendChild($dom->createElement($key)); if ($attributes) { foreach ($attributes as $attrKey => $attrValue) { $child->setAttribute($attrKey, $attrValue); } } $this->createNodes($dom, $value, $child); } } } } break; } } private function depluralize($word) { $rules = array( 'ss' => false, 'os' => 'o', 'ies' => 'y', 'xes' => 'x', 'oes' => 'o', 'ies' => 'y', 'ves' => 'f', 's' => null ); // Loop through all the rules foreach(array_keys($rules) as $key) { // If the end of the word doesn't match the key, it's not a candidate for replacement. if (substr($word, (strlen($key) * -1)) != $key) { continue; } // If the value of the key is false, stop looping and return the original version of the word. if ($key === false) { return $word; } // apply the rule return substr($word, 0, strlen($word) - strlen($key)) . $rules[$key]; } return $word; } }
- URLS pour appeler le websrvice (testé en ligne de commande) :
- curl http://localhost/webservices/rest/resource/responses
- curl http://localhost/webservices/rest/resource/responses/format/xml
- curl http://localhost/webservices/rest/resource/responses/format/json
- curl http://localhost/webservices/rest/resource/responses/format/html
- curl http://localhost/webservices/rest/resource/questions
...
Tout aide, exemple de web services avec rest et amélioration de ma méthode est la bienvenue
Merci pour vos retour les Zender's
Dernière modification par GueloSuperStar (28-05-2013 19:01:54)
Hors ligne
Le post est un peu vieux zd_flo, j'espère pour GueloSuperStar qu'il s'est débloqué depuis le temps...
Quite à déterrer, autant répondre à la question à l'aide des outils d'aujourd'hui : tu peux utiliser Apigility pour construire une api rest avec un projet ZF1.
Hors ligne