introduction to zend framework web services
TRANSCRIPT
![Page 1: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/1.jpg)
Zend Framework “at your service”
Michelangelo van DamMacq Electronique 2010, Brussels
![Page 2: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/2.jpg)
WARNING
Used EnvironmentPHP 5.3.2
Zend Framework 1.10.4MySQL 5.1.32
Examples might not work on another environment
![Page 3: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/3.jpg)
Michelangelo van Dam
• Independent Consultant
• Zend Certified Engineer (ZCE)
- PHP 4 & PHP 5
- Zend Framework• Co-Founder of PHPBenelux• Shepherd of “elephpant” herds
![Page 4: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/4.jpg)
What is Zend Framework
A loosly-coupled framework with a flexible architecture that lets you easily build modern web applications and web servicesMatthew Weier O’Phinney - Chief Architect Zend Framework
![Page 5: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/5.jpg)
Why a service ?
• opening up existing API- internal applications- external applications- additional functionality• support to more devices• portability and flexibility
![Page 6: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/6.jpg)
Important components
• Zend_Soap- Zend_Soap_Server- Zend_Soap_Client- Zend_Soap_Wsdl• Zend_Rest- Zend_Rest_Server- Zend_Rest_Client• Zend_XmlRpc- Zend_XmlRpc_Server- Zend_XmlRpc_Client- Zend_XmlRpc_Request- Zend_XmlRpc_Response
![Page 7: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/7.jpg)
Example service
• Time registration- list time sheets- add a new task- edit an existing task- delete an existing task
![Page 8: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/8.jpg)
MVC approach
• time module- controllers (for displaying listing and forms)- actions (for listing, adding, editing and deleting)- models (for access to database)- forms (for filtering, validation and rendering forms)
![Page 9: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/9.jpg)
Common behavior
• all “logic” is put in the controller• actions = API interface• downside- not flexible towards other clients- difficult to provide maintenance- not reusable design
![Page 10: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/10.jpg)
Time_IndexController
Time ModuleindexAction
- lists registered tasks- links to the form - for adding task - for editing task - for deleting task
editAction- displays a form - for adding task - for editing task
registerAction- processes form data - validating data - storing data in db
deleteAction- deletes task
![Page 11: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/11.jpg)
API Design
• moving logic- out the controller- in an API class• structures the application• is better testable• is better maintainable
![Page 12: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/12.jpg)
My_Api_Timesheet
Time APIlistTasks
- lists registered tasksregisterNewTask
- for adding task
editExistingTask- for modifying task
deleteExistingTask- deletes task
![Page 13: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/13.jpg)
Simple ?
![Page 14: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/14.jpg)
API output channels
API
Web
XML
SOAP
XMLRPC
Internal
JSON … REST
![Page 15: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/15.jpg)
Timesheet API
![Page 16: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/16.jpg)
DocBlocks are important!
• DocBlocks are very important !- provide quality API documentation- can be used as reference for the service !!!
![Page 17: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/17.jpg)
Automated API docs
![Page 18: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/18.jpg)
My_Api_Timesheet<?phpclass My_Api_Timesheet{}
![Page 19: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/19.jpg)
listTasks/** * List all tasks for a given user * * @param int $user * @param int $limit * @return array */public function listTasks($user, $limit = null){ $array = array (); $timesheet = new Time_Model_Timesheet(); if (null !== ($result = $timesheet->fetchAll(array ( 'user_id = ?' => $user, ), array ('date DESC', 'start_time ASC'), $limit))) { foreach ($result as $entry) { $array[] = $entry->toArray(); } } return $array;}
![Page 20: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/20.jpg)
registerNewTask/** * Register a new task * * @param int $user The ID of the user * @param int $customer The ID of the customer * @param int $task The ID of the task * @param string $date A date formatted as YYYY-mm-dd * @param string $start The starting time as HH:mm:ss * @param string $end The ending time as HH:mm:ss * @param string $description A short description * @return bool TRUE if registration succeeded * @throws My_Api_Timesheet_Exception */
![Page 21: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/21.jpg)
registerNewTaskpublic function registerNewTask( $user, $customer, $task, $date, $start, $end, $description){ $timesheet = new Time_Model_Timesheet(); $timesheet->setUserId($user) ->setCustomerId($customer) ->setTaskId($task) ->setDate($date) ->setStartTime($start) ->setEndTime($end) ->setDescription($description); $validator = $this->_validate($timesheet); if (false === $validator) { require_once 'My/Api/Timesheet/Exception.php'; throw new My_Api_Timesheet_Exception('Invalid data provided'); } $timesheet->save(); return true;}
![Page 22: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/22.jpg)
editExistingTask/** * Modify an existing task * * @param int $id The ID of an existing Task * @param int $user The ID of the user * @param int $customer The ID of the customer * @param int $task The ID of the task * @param string $date A date formatted as YYYY-mm-dd * @param string $start The starting time as HH:mm:ss * @param string $end The ending time as HH:mm:ss * @param string $description A short description * @return bool TRUE if registration succeeded * @throws My_Api_Timesheet_Exception */
![Page 23: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/23.jpg)
editExistingTaskpublic function editExistingTask( $id, $user, $customer, $task, $date, $start, $end, $description){ $timesheet = new Time_Model_Timesheet(); $timesheet->setId($id) ->setUserId($user) ->setCustomerId($customer) ->setTaskId($task) ->setDate($date) ->setStartTime($start) ->setEndTime($end) ->setDescription($description); $validator = $this->_validate($timesheet); if (false === $validator) { require_once 'My/Api/Timesheet/Exception.php'; throw new My_Api_Timesheet_Exception('Invalid data provided'); } $timesheet->save(); return true;}
![Page 24: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/24.jpg)
deleteExistingTask/** * Removes an existing task * * @param int $id The ID of an existing Task * @param int $user The ID of the user * @return bool TRUE if registration succeeded */public function deleteExistingTask($id, $user){ $timesheet = new Time_Model_Timesheet(); $timesheet->setId($id) ->setUserId($user); $validator = $this->_validate($timesheet); if (false === $validator) { require_once 'My/Api/Timesheet/Exception.php'; throw new My_Api_Timesheet_Exception('Invalid data provided'); } $timesheet->delete(array ( 'id = ?' => $timesheet->getId(), 'user_id = ?' => $timesheet->getUserId(), )); return true;}
![Page 25: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/25.jpg)
_validate/** * Private validation method * * @param Time_Model_Timesheet $timesheet * @return bool TRUE if validated, FALSE if invalid */private function _validate(Time_Model_Timesheet $timesheet){ $result = true; $validator = new Time_Form_Register(); $customer = new Time_Model_Customer(); $task = new Time_Model_Task(); $validator->getElement('customer_id')->setMultiOptions($customer->toSelect()); $validator->getElement('task_id')->setMultiOptions($task->toSelect()); if (!$validator->isValid($timesheet->toArray())) { $result = false; } return $result;}
![Page 26: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/26.jpg)
Zend_XmlRpc
![Page 27: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/27.jpg)
XmlRpc Server<?phpclass Time_XmlRpcController extends Zend_Controller_Action{ public function indexAction() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); require_once 'My/Api/Timesheet.php'; $server = new Zend_XmlRpc_Server(); $server->setClass('My_Api_Timesheet'); echo $server->handle(); }}
![Page 28: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/28.jpg)
XmlRpc Client<?phpclass Time_XmlRpcClientController extends Zend_Controller_Action{ protected $_client; public function init() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $this->_client = new Zend_XmlRpc_Client( 'http://www.demo.local/Time/XmlRpc'); }…}
![Page 29: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/29.jpg)
XmlRpc Clientpublic function newAction(){ $client = $this->_client; $request = new Zend_XmlRpc_Request(); $request->setMethod('registerNewTask'); $request->setParams(array ( 2, // user ID 3, // customer ID 3, // task ID '2010-03-28', // date '18:00:00', // start time '23:30:00', // end time 'Demo XmlRpc add', // description )); $result = null; $errors = array (); try { $client->doRequest($request); $result = $client->getLastResponse()->getReturnValue(); } catch (Zend_XmlRpc_Client_FaultException $e) { $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (Zend_XmlRpc_Client_HttpException $e) { $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (My_Api_Timesheet_Exception $e) { $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}"; }}
![Page 30: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/30.jpg)
XmlRpc Clientpublic function editAction(){ $client = $this->_client; $request = new Zend_XmlRpc_Request(); $request->setMethod('editExistingTask'); $request->setParams(array ( 5, // ID 2, // user ID 3, // customer ID 4, // task ID '2010-03-28', // date '18:00:00', // start time '23:30:00', // end time 'Demo XmlRpc add', // description )); $result = null; $errors = array (); try { $client->doRequest($request); $result = $client->getLastResponse()->getReturnValue(); } catch (Zend_XmlRpc_Client_FaultException $e) { $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (Zend_XmlRpc_Client_HttpException $e) { $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (My_Api_Timesheet_Exception $e) { $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}"; }}
![Page 31: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/31.jpg)
XmlRpc Clientpublic function deleteAction(){ $client = $this->_client; $request = new Zend_XmlRpc_Request(); $request->setMethod('deleteExistingTask'); $request->setParams(array ( 6, // ID 2, // user ID )); $result = null; $errors = array (); try { $client->doRequest($request); $result = $client->getLastResponse()->getReturnValue(); if ($client->getLastResponse()->isFault()) { $result = $client->getLastResponse()->getFault(); } } catch (Zend_XmlRpc_Client_FaultException $e) { $errors['fault'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (Zend_XmlRpc_Client_HttpException $e) { $errors['http'] = "[{$e->getCode()}]: {$e->getMessage()}"; } catch (My_Api_Timesheet_Exception $e) { $errors['api'] = "[{$e->getCode()}]: {$e->getMessage()}"; }}
![Page 32: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/32.jpg)
Zend_Soap
![Page 33: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/33.jpg)
SOAP Server<?phpclass Time_SoapController extends Zend_Controller_Action{ public function indexAction() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $options = array (); $server = new Zend_Soap_AutoDiscover(); $server->setClass('My_Api_Timesheet'); $server->handle(); }}
![Page 34: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/34.jpg)
SOAP Client<?phpclass Time_SoapClientController extends Zend_Controller_Action{ protected $_client; public function init() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $this->_client = new Zend_Soap_Client( 'http://www.demo.local/Time/soap?wsdl', array ()); }
public function indexAction() { $result = $this->_client->listTasks(2, 2); $this->getResponse()->setHeader('Content-Type', 'text/xml; Charset=UTF-8'); echo $this->_client->getLastResponse(); }…
![Page 35: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/35.jpg)
SOAP Clientpublic function addAction() { Zend_Debug::dump($this->_client->registerNewTask( 2, 2, 3, '2010-03-30', '18:00:00', '23:30:00','Setting up SOAP')); } public function editAction() { Zend_Debug::dump($this->_client->editExistingTask( 7, 2, 2, 3, '2010-03-30', '18:00:00', '23:30:00','Testing SOAP')); } public function deleteAction() { Zend_Debug::dump($this->_client->deleteExistingTask(7, 2)); }}
![Page 36: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/36.jpg)
Zend_Rest
![Page 37: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/37.jpg)
REST Server<?phpclass Time_RestController extends Zend_Controller_Action{ public function indexAction() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $server = new Zend_Rest_Server(); $server->setClass('My_Api_Timesheet'); $server->handle(); }}
![Page 38: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/38.jpg)
REST Client<?php
class Time_RestClientController extends Zend_Controller_Action{ protected $_client; public function init() { $this->_helper->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); $this->_client = new Zend_Rest_Client('http://www.demo.local/Time/rest'); }
public function indexAction() { $this->_client->listTasks(2); Zend_Debug::dump($this->_client->get()); }}
![Page 39: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/39.jpg)
Patterns ???
![Page 40: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/40.jpg)
Conclusion
moving functionality out the controllerinto a library API
=saves time
1 api = XmlRpc + SOAP + REST + …
![Page 41: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/41.jpg)
Recommended readingWeb Services EssentialsEthan Cerami
O’Reilly
Programming Web Services with XML-RPCSimon St. Laurent, Joe Johnston, Edd Dumbill, Dave Winer
O’Reilly
![Page 42: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/42.jpg)
Recommended readingRESTful Web ServicesLeonard Richardson, Sam Ruby
O’Reilly
Programming Web Services with XML-RPCJames Snell, Doug Tidwell, Pavel Kulchenko
O’Reilly
![Page 43: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/43.jpg)
We need you help !!!
![Page 44: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/44.jpg)
Feedback is important
• find a bug ?- test it- report it- send a patch/fix• need a non-existing component- submit proposal• like Zend Framework- blog about it- talk about it• translations
![Page 45: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/45.jpg)
ZF Bug hunt days
Zend Framework Bughuntdaysevery 3rd Thursday and Friday of the month
http://framework.zend.com/issuesIRC (irc.freenode.net) #zftalk.dev
prizes:recognition and appreciation of the community
Free subscription for 1 year on php|Architect magazineZend Framework t-shirt
![Page 46: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/46.jpg)
ZF issue tracker
![Page 47: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/47.jpg)
• When: June 10 - 12 2010• Where: Amsterdam RAI• Tickets: http://phpconference.nl• Early bird: ends April 30, 2010 (Queen’s Day)
![Page 48: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/48.jpg)
• annual event• improve code coverage• test php core source code• improve quality of PHP
PHPB ENELUX
![Page 49: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/49.jpg)
• When: May 29, 2010• Where: <to-be-defined>• Updates: • web: http://www.phpbenelux.eu• twitter: @phpbenelux
PHPB ENELUX
![Page 50: Introduction to Zend Framework web services](https://reader034.vdocuments.us/reader034/viewer/2022042511/55d4fccebb61ebaa528b4667/html5/thumbnails/50.jpg)
Thank you !
Slides on Slidesharehttp://www.slideshare.net/group/macqel
Give feedback on Joind.inhttp://joind.in/1263