Introduction to Zend Framework web services

7,923 views
7,702 views

Published on

A basic introduction to setting up and using web services with Zend Framework

Published in: Technology
1 Comment
8 Likes
Statistics
Notes
  • Where can i download the demo code?
       Reply 
    Are you sure you want to  Yes  No
    Your message goes here
No Downloads
Views
Total views
7,923
On SlideShare
0
From Embeds
0
Number of Embeds
60
Actions
Shares
0
Downloads
158
Comments
1
Likes
8
Embeds 0
No embeds

No notes for slide

Introduction to Zend Framework web services

  1. 1. Zend Framework “at your service” Michelangelo van Dam Macq Electronique 2010, Brussels
  2. 2. WARNING Used Environment PHP 5.3.2 Zend Framework 1.10.4 MySQL 5.1.32 Examples might not work on another environment
  3. 3. Michelangelo van Dam • Independent Consultant • Zend Certified Engineer (ZCE) - PHP 4 & PHP 5 - Zend Framework • Co-Founder of PHPBenelux • Shepherd of “elephpant” herds
  4. 4. What is Zend Framework A loosly-coupled framework with a flexible architecture that lets you easily build modern web applications and web services Matthew Weier O’Phinney - Chief Architect Zend Framework
  5. 5. Why a service ? •- opening up existing API internal applications - external applications - additional functionality • support to more devices • portability and flexibility
  6. 6. 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
  7. 7. Example service •- Time registration list time sheets - add a new task - edit an existing task - delete an existing task
  8. 8. 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)
  9. 9. 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
  10. 10. Time Module Time_IndexController indexAction editAction - lists registered tasks - displays a form - links to the form - for adding task - for adding task - for editing task - for editing task - for deleting task registerAction deleteAction - processes form data - deletes task - validating data - storing data in db
  11. 11. API Design •- moving logic out the controller - in an API class • structures the application • is better testable • is better maintainable
  12. 12. Time API My_Api_Timesheet listTasks registerNewTask - lists registered tasks - for adding task editExistingTask deleteExistingTask - for modifying task - deletes task
  13. 13. Simple ?
  14. 14. API output channels Web Internal SOAP XML API XMLRPC JSON … REST
  15. 15. Timesheet API
  16. 16. DocBlocks are important! •- DocBlocks are very important ! provide quality API documentation - can be used as reference for the service !!!
  17. 17. Automated API docs
  18. 18. My_Api_Timesheet <?php class My_Api_Timesheet { }
  19. 19. 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; }
  20. 20. 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 */
  21. 21. registerNewTask public 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; }
  22. 22. 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 */
  23. 23. editExistingTask public 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; }
  24. 24. 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; }
  25. 25. _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; }
  26. 26. Zend_XmlRpc
  27. 27. XmlRpc Server <?php class 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(); } }
  28. 28. XmlRpc Client <?php class 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'); } … }
  29. 29. XmlRpc Client public 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()}"; } }
  30. 30. XmlRpc Client public 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()}"; } }
  31. 31. XmlRpc Client public 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()}"; } }
  32. 32. Zend_Soap
  33. 33. SOAP Server <?php class 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(); } }
  34. 34. SOAP Client <?php class 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(); } …
  35. 35. SOAP Client public 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)); } }
  36. 36. Zend_Rest
  37. 37. REST Server <?php class 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(); } }
  38. 38. 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()); } }
  39. 39. Patterns ???
  40. 40. Conclusion moving functionality out the controller into a library API = saves time 1 api = XmlRpc + SOAP + REST + …
  41. 41. Recommended reading Web Services Essentials Ethan Cerami O’Reilly Programming Web Services with XML-RPC Simon St. Laurent, Joe Johnston, Edd Dumbill, Dave Winer O’Reilly
  42. 42. Recommended reading RESTful Web Services Leonard Richardson, Sam Ruby O’Reilly Programming Web Services with XML-RPC James Snell, Doug Tidwell, Pavel Kulchenko O’Reilly
  43. 43. We need you help !!!
  44. 44. 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
  45. 45. ZF Bug hunt days Zend Framework Bughuntdays every 3rd Thursday and Friday of the month http://framework.zend.com/issues IRC (irc.freenode.net) #zftalk.dev prizes: recognition and appreciation of the community Free subscription for 1 year on php|Architect magazine Zend Framework t-shirt
  46. 46. ZF issue tracker
  47. 47. • When: June 10 - 12 2010 • Where: Amsterdam RAI • Tickets: http://phpconference.nl • Early bird: ends April 30, 2010 (Queen’s Day)
  48. 48. PHP BENELUX • annual event • improve code coverage • test php core source code • improve quality of PHP
  49. 49. PHP BENELUX • When: May 29, 2010 • Where: <to-be-defined> • Updates: • web: http://www.phpbenelux.eu • twitter: @phpbenelux
  50. 50. Thank you ! Slides on Slideshare http://www.slideshare.net/group/macqel Give feedback on Joind.in http://joind.in/1263

×