introduction to zend framework web services

50
Zend Framework “at your service” Michelangelo van Dam Macq Electronique 2010, Brussels

Upload: michelangelo-van-dam

Post on 20-Aug-2015

7.007 views

Category:

Technology


4 download

TRANSCRIPT

Page 1: Introduction to Zend Framework web services

Zend Framework “at your service”

Michelangelo van DamMacq Electronique 2010, Brussels

Page 2: Introduction to Zend Framework web services

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

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

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

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

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

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

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

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

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

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

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

Simple ?

Page 14: Introduction to Zend Framework web services

API output channels

API

Web

XML

SOAP

XMLRPC

Internal

JSON … REST

Page 15: Introduction to Zend Framework web services

Timesheet API

Page 16: Introduction to Zend Framework web services

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

Automated API docs

Page 18: Introduction to Zend Framework web services

My_Api_Timesheet<?phpclass My_Api_Timesheet{}

Page 19: Introduction to Zend Framework web services

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

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

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

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

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

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

_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

Zend_XmlRpc

Page 27: Introduction to Zend Framework web services

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

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

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

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

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

Zend_Soap

Page 33: Introduction to Zend Framework web services

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

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

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

Zend_Rest

Page 37: Introduction to Zend Framework web services

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

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

Patterns ???

Page 40: Introduction to Zend Framework web services

Conclusion

moving functionality out the controllerinto a library API

=saves time

1 api = XmlRpc + SOAP + REST + …

Page 41: Introduction to Zend Framework web services

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

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

We need you help !!!

Page 44: Introduction to Zend Framework web services

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 46: Introduction to Zend Framework web services

ZF issue tracker

Page 47: Introduction to Zend Framework web services

• 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

• annual event• improve code coverage• test php core source code• improve quality of PHP

PHPB ENELUX

Page 49: Introduction to Zend Framework web services

• 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

Thank you !

Slides on Slidesharehttp://www.slideshare.net/group/macqel

Give feedback on Joind.inhttp://joind.in/1263