Successfully reported this slideshow.

RESTful modules in zf2

14

Share

Loading in …3
×
1 of 28
1 of 28

RESTful modules in zf2

14

Share

Download to read offline

Description

Just a simple introduction to RESTful modules in ZF2

Transcript

  1. 1. RESTful Modules in ZF2 Walter Dal Mut – walter.dalmut@gmail.com - @walterdalmut https://github.com/wdalmut @walterdalmut - www.corley.it - www.upcloo.com
  2. 2. About Me • Walter Dal Mut (@walterdalmut) • Electronic Engineer • Polytechnic University of Turin • Startupper • Corley S.r.l. – www.corley.it • Cloud Computing Services • UpCloo Ltd. – www.upcloo.com • Semantic Most Related Links service @walterdalmut - www.corley.it - www.upcloo.com
  3. 3. Summary • REST introduction • REST constraints • Types of RESTful services • ZF2 RESTful modules • RESTful ZF2 URI tunneling module • RESTful ZF2 CRUD module @walterdalmut - www.corley.it - www.upcloo.com
  4. 4. RESTful? What it means in few words… • Representational State Transfer (REST) • Architecture is based on Client-Server • Clients initiate requests to servers; servers process requests and return appropriate responses • Flexible, the application must know messages format • XML • JSON • Etc. @walterdalmut - www.corley.it - www.upcloo.com
  5. 5. RESTful services are resource centric • Resources (sources of specific information) • Each resource is referenced with a global identifier (URI, etc.) • Any number of connectors can mediate the request • Clients • Servers • Caches • Tunnels @walterdalmut - www.corley.it - www.upcloo.com
  6. 6. REST Constraints • Client-Server • A uniform interface separates clients from servers. • Stateless • The client–server communication is further constrained by no client context being stored on the server between requests. • Cacheable • Clients can cache responses • Layered System • Intermediary servers may improve system scalability by enabling load-balancing and by providing shared caches. They may also enforce security policies. • Uniform interface • Simplify and decouples the architecture @walterdalmut - www.corley.it - www.upcloo.com
  7. 7. Several types of RESTful services • URI Templates • http://rest.domain.tld/order/{orderID} • One of the major uses for URI templates is as human- and machine-readable documentation. • URI Tunneling • http://rest.domain.tld/PlaceOrder?pizza=margherita&type=classic • Rest.domain.tld  service • PlaceOrder method • Pizza=margherita&type=classic  arguments • POX – Plain Old XML over HTTP • Similar to URI Tunneling but information will be sent as XML document in the HTTP request from the customer. @walterdalmut - www.corley.it - www.upcloo.com
  8. 8. POX – Plain Old XML over HTTP example POST /PlaceOrder HTTP/1.1 Content-Type: application/xml Client application Application domain <Order> <Pizza> <Name>margherita</Name> <Type>classic</Type> </Pizza> </Order> HTTP/1.1 200 OK <OrderConfirmation> <OrderID>1345</OrderID> </OrderConfirmation> @walterdalmut - www.corley.it - www.upcloo.com
  9. 9. CRUD Webservices • CRUD what it means? • Create, Read, Update and Delete • Patterns for manipulating resources across the network • Extended usage of HTTP verbs • GET • POST • PUT • DELETE • Using HTTP as an application protocol instead of a transport protocol • Web is really a big framework for building distributed systems. @walterdalmut - www.corley.it - www.upcloo.com
  10. 10. HTTP verbs in CRUD services • Get Read Operation • Used to retrive resource details • http://rest.service.tld/order/10 • Post  Create Operation • Used to create new resources • Put Update Operation • Used to update existing resources • Delete Delete Operation • Used to delete existing resources POST/PUT can be exchanged and sometimes PUT/DELETE can be excluded to enable javascript integration (PUT/DELETE not supported browser side [HTTP_X_HTTP_METHOD_OVERRIDE parameter]) @walterdalmut - www.corley.it - www.upcloo.com
  11. 11. CRUD Summary Verb URI or Template Use POST /order Create a new order, and upon success, receive a Location header specifying the new order’s URI. GET /order/{id} Request the current state of the order specified by the URI. PUT /order/{id} Update an order at the given URI with new information, providing the full representation. DELETE /order/{id} Logically remove the order identified by the given URI. @walterdalmut - www.corley.it - www.upcloo.com
  12. 12. Status code definition (short list) • 2xx (Positives) • 200 OK – The request has succeeded. • 201 Created – The server accept the request and it has created the resource. • 202 Accepted – The request has been accepted for processing, but the processing has not been completed. • 4xx (Client Errors) • 400 Bad Request – The request could not be understood by the server due to malformed syntax. • 401 Unauthorized – The request requires user authentication. • 403 Forbidden – The server understood the request, but is refusing to fulfill it. • 404 Not found – The server has not found anything matching the Request-URI. • 405 Method not allowed – The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. • 5xx (Server Errors) • 500 Internal Server Error – The server encountered an unexpected condition which prevented it from fulfilling the request. • 501 Not implemented – The server does not support the functionality required to fulfill the request. • 503 Service unavailable – The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. @walterdalmut - www.corley.it - www.upcloo.com
  13. 13. RESTful module idea • Router • Wire requests to RESTful controllers • RESTful Controllers requests Router • Uses HTTP verbs to call dedicated actions • Query models in order to serve RESTful responses Models • POST Processors Controllers • Create valid messages using formats • JSON Responses POST • XML Processor • Etc. @walterdalmut - www.corley.it - www.upcloo.com
  14. 14. Realize ZF2 tunneling RESTful module • ZF1 provides «Zend_Rest_Server» that realize URI tunneling • We can realize the same thing in 2 minutes thanks to ZF2 flexibility. • We need to configure • Router • Events • A simple example here: • https://github.com/wdalmut/ZF2-Tunneling-Restful-Module-Skeleton @walterdalmut - www.corley.it - www.upcloo.com
  15. 15. ZF2 URI Tunneling - Configuration <?php return array( We have created a simple base route «/tunnel» 'controllers' => array( 'invokables' => array( and a dynamic rule that select a «model» and an 'index' => 'TunnelingRestController', ) attached «action» ), 'router' => array( 'routes' => array( 'tunneling' => array( In simple words 'type' => 'ZendMvcRouterHttpSegment', 'options' => array( • http://my-app.local/tunnel/menu/get?id=1 'route' => '/tunnel', 'defaults' => array( • «menu» 'controller' => 'index', 'action' => 'index' • The model «TunnelingModelMenu» ), ), • «get» 'may_terminate' => true, 'child_routes' => array( • The model action «get()» 'default' => array( 'type' => 'ZendMvcRouterHttpSegment', • «id=1> 'options' => array( 'route' => '[/:model/:action]', • The action parameters «get(1)» 'constraints' => array( 'controller' => 'index', 'model' => '[a-zA-Z][a-zA-Z0-9_]*', 'action' => '[a-zA-Z][a-zA-Z0-9_]*' ), ), ), ), ), ), ) ); @walterdalmut - www.corley.it - www.upcloo.com
  16. 16. ZF2 URI Tunneling - Controller <?php namespace TunnelingRest; The base «AbstractController» is very flexible Use … and enable us to use the «dispatch» action to class Controller extends AbstractController realize what we need in few lines. { public function onDispatch(MvcEvent $e) { $routeMatch = $e->getRouteMatch(); In practice we allocate the model and call the $params = $routeMatch->getParams(); $vars = get_object_vars($e->getRequest()->getQuery()); requested action. The return variable is used as $filter = new ZendFilterFilterChain(); response. $filter->attach(new ZendFilterWordDashToCamelCase()); $filter->attach(new ZendFilterCallback("lcfirst")); $action = $filter->filter($params["action"]); $filter->attach(new ZendFilterCallback("ucfirst")); In case of missing model or missing action an $model = $filter->filter($params["model"]); «InvalidArgumentException» is thrown. $classname = "TunnelingModel{$model}"; if (class_exists($classname)) { $clazz = new $classname; if (property_exists($clazz, $action)) { $ret = call_user_func_array(array($clazz, $action), $vars); $e->setResult($ret); return; } else { throw new InvalidArgumentException("Method "{$action}" doesn't exists'"); } } else { throw new InvalidArgumentException("Class "{$classname}" doesn't exists'"); } } } @walterdalmut - www.corley.it - www.upcloo.com
  17. 17. ZF2 URI Tunneling – Model example <?php namespace TunnelingModel; As you can see, the «model» is a simple class definition. class Menu { public function get($id) { • /tunnel/menu/get?id=1 return array("id" => $id); } • /tunnel/menu/add?x=pizza&y=4 public function add($name, $value) { Very simple implementation return array("name" => $name, "value" => $value); } } @walterdalmut - www.corley.it - www.upcloo.com
  18. 18. ZF2 URI Tunneling – JSON responses <?php namespace Tunneling; Thanks to events we can wire controller output use ZendMvcMvcEvent; to a post processor that converts responses in class Module json messages. { public function onBootstrap($e) { /** @var ZendModuleManagerModuleManager $moduleManager */ • Attach a «postProcess» action and create a $moduleManager = $e->getApplication()->getServiceManager()->get('modulemanager'); /** @var ZendEventManagerSharedEventManager $sharedEvents */ json message. $sharedEvents = $moduleManager->getEventManager()->getSharedManager(); $sharedEvents->attach( 'ZendMvcControllerAbstractController', MvcEvent::EVENT_DISPATCH, array($this, 'postProcess'), -100 ); } //… public function postProcess(MvcEvent $e) { $routeMatch = $e->getRouteMatch(); if (strpos($routeMatch->getMatchedRouteName(), "tunneling") !== false) { $e->getResponse()->setContent(json_encode($e->getResult()->getVariables())); return $e->getResponse(); } } } @walterdalmut - www.corley.it - www.upcloo.com
  19. 19. ZF2 RESTful CRUD modules • ZF2 provides a base controller class that can help us to realize RESTful modules in few steps • ZendMvcControllerAbstractRestfulController • CRUD based implementation (Extended) • get($id) • delete($id) • update($id) • create($id) @walterdalmut - www.corley.it - www.upcloo.com
  20. 20. ZF2 RESTful CRUD module example • Clone ZF2 Skeleton Application • Git clone https://github.com/zendframework/ZendSkeletonApplication.git my-app • Git submodule init • Git submodule update • Clone a ZF2 RESTful module • Git submodule add https://github.com/wdalmut/ZF2-Restful-Module-Skeleton.git module/Main • Add «Main» module into «configs/application.config.php» • Create you application virtual host and try it • http://my-app.local/rest/info/json [getList] • http://my-app.local/rest/info/json/1 [get] • curl –X POST –d ‘hello=world’ http://my-app.local/rest/info [create] • curl –X PUT –d ‘hello=ciao’ http://my-app.local/rest/info/1 [update] • curl –X DELETE http://my-app.local/rest/info/1 [delete] @walterdalmut - www.corley.it - www.upcloo.com
  21. 21. RESTful Controllers <?php • RESTful Controller should extends AbstractRestfulController namespace MainController; • 5 abstract methods (CRUD + List) use ZendMvcControllerAbstractRestfulController; • getList class InfoController extends AbstractRestfulController { • GET operation without parameters public function getList() { • /rest/json/info } return array('ciao' => 'mondo'); • Get public function get($id) • READ resource with parameters (ID) { • /rest/json/info/1 } • Delete public function delete($id) { • DELETE a resource } • Update public function update($id, $data) • UPDATE a resource { • Create } • CREATE a new resource public function create($data = null) { } } @walterdalmut - www.corley.it - www.upcloo.com
  22. 22. First of all play with routes 'router' => array( 'routes' => array( • Create a base route /rest that enable also formatters 'restful' => array( 'type' => 'ZendMvcRouterHttpSegment', • Formatter allow us to switch easly to JSON, 'options' => array( 'route' => '/rest[/:formatter]', XML etc. 'constraints' => array( • Child routes play with controller and identifiers 'formatter' => '[a-zA-Z0-9_-]*', ), ), 'may_terminate' => true, 'child_routes' => array( 'default' => array( 'type' => 'ZendMvcRouterHttpSegment', 'options' => array( 'route' => '[/:controller[/:id]]', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[a-zA-Z0-9_-]*' ), ), ), ), ), ), @walterdalmut - www.corley.it - www.upcloo.com
  23. 23. Formatters • RESTful services can handle different type of messages • JSON • XML • Images • Etc • The high modularity of ZF2 MVC implementation enable us to add different layers of abstractions and formatters is one of this. • Client must know what kind of messages type have to handle. • Post Processors are used to render messages @walterdalmut - www.corley.it - www.upcloo.com
  24. 24. Formatters «configs/module.config.php» 'errors' => array( 'post_processor' => 'json-pp', • The configuration allows us to define different «post processors» 'show_exceptions' => array( 'message' => true, • Errors can be detailed more, for example traces, messages etc. 'trace' => true ) ), 'di' => array( 'instance' => array( 'alias' => array( 'json-pp' => 'MainPostProcessorJson', 'jsonp-pp' => 'MainPostProcessorJsonp', 'image-pp' => 'MainPostProcessorImage' ) ) ), @walterdalmut - www.corley.it - www.upcloo.com
  25. 25. Wiring events (Module.php) /** * @param MvcEvent $e */ public function onBootstrap($e) • Event position -100 { /** @var ZendModuleManagerModuleManager $moduleManager */ • Handle post processors $moduleManager = $e->getApplication()->getServiceManager()->get('modulemanager'); /** @var ZendEventManagerSharedEventManager $sharedEvents */ • Event position 100 $sharedEvents = $moduleManager->getEventManager()->getSharedManager(); • Handle HTTP Method Override $sharedEvents->attach( • Event position 999 'ZendMvcControllerAbstractRestfulController', MvcEvent::EVENT_DISPATCH, • Handle errors array($this, 'postProcess'), -100 ); $sharedEvents->attach( 'MainControllerInfoController', MvcEvent::EVENT_DISPATCH, array($e->getApplication()->getServiceManager()->get('MainHttpRestful'), 'onDispatch'), 100 ); $sharedEvents->attach( 'ZendMvcApplication', MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'errorProcess'), 999 ); } @walterdalmut - www.corley.it - www.upcloo.com
  26. 26. Attach Post Processor to Actions public function postProcess(MvcEvent $e) { $routeMatch = $e->getRouteMatch(); $formatter = $routeMatch->getParam('formatter', false); $di = $e->getTarget()->getServiceLocator()->get('di'); if ($formatter !== false) { if ($e->getResult() instanceof ZendViewModelViewModel) { if (($e->getResult()->getVariables())) { $vars = $e->getResult()->getVariables(); } else { $vars = null; } } else { $vars = $e->getResult(); } $postProcessor = $di->get($formatter . '-pp', array( 'request' => $e->getRequest(), 'response' => $e->getResponse(), 'vars' => $vars, )); $postProcessor->process(); return $postProcessor->getResponse(); } return null; } @walterdalmut - www.corley.it - www.upcloo.com
  27. 27. Example of JSON Post Processor <?php <?php namespace MainPostProcessor; namespace MainPostProcessor; /** abstract class AbstractPostProcessor * { */ protected $_vars = null; class Json extends AbstractPostProcessor private $_request = null; { private $_response = null; public function process() { public function __construct $result = json_encode($this->_vars); (ZendHttpRequest $request, ZendHttpResponse $response, $vars = null) { $headers = $this->getResponse()->getHeaders(); $this->_vars = $vars; $headers->addHeaderLine('Content-Type', 'application/json'); $this->_response = $response; $this->_request = $request; $this->getResponse()->setHeaders($headers); } $this->getResponse()->setContent($result); } public function getResponse() } { return $this->_response; } public function getRequest() { return $this->_request; } abstract public function process(); } @walterdalmut - www.corley.it - www.upcloo.com
  28. 28. ZF2 RESTful Modules Thanks for listening… Any questions? @walterdalmut - www.corley.it - www.upcloo.com

Editor's Notes

  • Ringrazione l’organizzazione dello ZFDAY, gli sponsor e tutte le persone presenti.
  • Abbiamo solo 30 minuti quindi fare un veloce escursus sui service RESTful e vedremo come realizzare due moduli ZF2.Un primo molto semplice, ispirato a Zend_Rest_Server di ZF1 Un secondo utilizzando un componente integrato nella libreria ZF2
  • Il termite REST è stato coniato nel 2000 da Roy Fielding, uno degli autori del protocollo HTTP, per descrivere un sistema che permette di descrivere ed identificare le risorse web.
  • Description

    Just a simple introduction to RESTful modules in ZF2

    Transcript

    1. 1. RESTful Modules in ZF2 Walter Dal Mut – walter.dalmut@gmail.com - @walterdalmut https://github.com/wdalmut @walterdalmut - www.corley.it - www.upcloo.com
    2. 2. About Me • Walter Dal Mut (@walterdalmut) • Electronic Engineer • Polytechnic University of Turin • Startupper • Corley S.r.l. – www.corley.it • Cloud Computing Services • UpCloo Ltd. – www.upcloo.com • Semantic Most Related Links service @walterdalmut - www.corley.it - www.upcloo.com
    3. 3. Summary • REST introduction • REST constraints • Types of RESTful services • ZF2 RESTful modules • RESTful ZF2 URI tunneling module • RESTful ZF2 CRUD module @walterdalmut - www.corley.it - www.upcloo.com
    4. 4. RESTful? What it means in few words… • Representational State Transfer (REST) • Architecture is based on Client-Server • Clients initiate requests to servers; servers process requests and return appropriate responses • Flexible, the application must know messages format • XML • JSON • Etc. @walterdalmut - www.corley.it - www.upcloo.com
    5. 5. RESTful services are resource centric • Resources (sources of specific information) • Each resource is referenced with a global identifier (URI, etc.) • Any number of connectors can mediate the request • Clients • Servers • Caches • Tunnels @walterdalmut - www.corley.it - www.upcloo.com
    6. 6. REST Constraints • Client-Server • A uniform interface separates clients from servers. • Stateless • The client–server communication is further constrained by no client context being stored on the server between requests. • Cacheable • Clients can cache responses • Layered System • Intermediary servers may improve system scalability by enabling load-balancing and by providing shared caches. They may also enforce security policies. • Uniform interface • Simplify and decouples the architecture @walterdalmut - www.corley.it - www.upcloo.com
    7. 7. Several types of RESTful services • URI Templates • http://rest.domain.tld/order/{orderID} • One of the major uses for URI templates is as human- and machine-readable documentation. • URI Tunneling • http://rest.domain.tld/PlaceOrder?pizza=margherita&type=classic • Rest.domain.tld  service • PlaceOrder method • Pizza=margherita&type=classic  arguments • POX – Plain Old XML over HTTP • Similar to URI Tunneling but information will be sent as XML document in the HTTP request from the customer. @walterdalmut - www.corley.it - www.upcloo.com
    8. 8. POX – Plain Old XML over HTTP example POST /PlaceOrder HTTP/1.1 Content-Type: application/xml Client application Application domain <Order> <Pizza> <Name>margherita</Name> <Type>classic</Type> </Pizza> </Order> HTTP/1.1 200 OK <OrderConfirmation> <OrderID>1345</OrderID> </OrderConfirmation> @walterdalmut - www.corley.it - www.upcloo.com
    9. 9. CRUD Webservices • CRUD what it means? • Create, Read, Update and Delete • Patterns for manipulating resources across the network • Extended usage of HTTP verbs • GET • POST • PUT • DELETE • Using HTTP as an application protocol instead of a transport protocol • Web is really a big framework for building distributed systems. @walterdalmut - www.corley.it - www.upcloo.com
    10. 10. HTTP verbs in CRUD services • Get Read Operation • Used to retrive resource details • http://rest.service.tld/order/10 • Post  Create Operation • Used to create new resources • Put Update Operation • Used to update existing resources • Delete Delete Operation • Used to delete existing resources POST/PUT can be exchanged and sometimes PUT/DELETE can be excluded to enable javascript integration (PUT/DELETE not supported browser side [HTTP_X_HTTP_METHOD_OVERRIDE parameter]) @walterdalmut - www.corley.it - www.upcloo.com
    11. 11. CRUD Summary Verb URI or Template Use POST /order Create a new order, and upon success, receive a Location header specifying the new order’s URI. GET /order/{id} Request the current state of the order specified by the URI. PUT /order/{id} Update an order at the given URI with new information, providing the full representation. DELETE /order/{id} Logically remove the order identified by the given URI. @walterdalmut - www.corley.it - www.upcloo.com
    12. 12. Status code definition (short list) • 2xx (Positives) • 200 OK – The request has succeeded. • 201 Created – The server accept the request and it has created the resource. • 202 Accepted – The request has been accepted for processing, but the processing has not been completed. • 4xx (Client Errors) • 400 Bad Request – The request could not be understood by the server due to malformed syntax. • 401 Unauthorized – The request requires user authentication. • 403 Forbidden – The server understood the request, but is refusing to fulfill it. • 404 Not found – The server has not found anything matching the Request-URI. • 405 Method not allowed – The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. • 5xx (Server Errors) • 500 Internal Server Error – The server encountered an unexpected condition which prevented it from fulfilling the request. • 501 Not implemented – The server does not support the functionality required to fulfill the request. • 503 Service unavailable – The server is currently unable to handle the request due to a temporary overloading or maintenance of the server. @walterdalmut - www.corley.it - www.upcloo.com
    13. 13. RESTful module idea • Router • Wire requests to RESTful controllers • RESTful Controllers requests Router • Uses HTTP verbs to call dedicated actions • Query models in order to serve RESTful responses Models • POST Processors Controllers • Create valid messages using formats • JSON Responses POST • XML Processor • Etc. @walterdalmut - www.corley.it - www.upcloo.com
    14. 14. Realize ZF2 tunneling RESTful module • ZF1 provides «Zend_Rest_Server» that realize URI tunneling • We can realize the same thing in 2 minutes thanks to ZF2 flexibility. • We need to configure • Router • Events • A simple example here: • https://github.com/wdalmut/ZF2-Tunneling-Restful-Module-Skeleton @walterdalmut - www.corley.it - www.upcloo.com
    15. 15. ZF2 URI Tunneling - Configuration <?php return array( We have created a simple base route «/tunnel» 'controllers' => array( 'invokables' => array( and a dynamic rule that select a «model» and an 'index' => 'TunnelingRestController', ) attached «action» ), 'router' => array( 'routes' => array( 'tunneling' => array( In simple words 'type' => 'ZendMvcRouterHttpSegment', 'options' => array( • http://my-app.local/tunnel/menu/get?id=1 'route' => '/tunnel', 'defaults' => array( • «menu» 'controller' => 'index', 'action' => 'index' • The model «TunnelingModelMenu» ), ), • «get» 'may_terminate' => true, 'child_routes' => array( • The model action «get()» 'default' => array( 'type' => 'ZendMvcRouterHttpSegment', • «id=1> 'options' => array( 'route' => '[/:model/:action]', • The action parameters «get(1)» 'constraints' => array( 'controller' => 'index', 'model' => '[a-zA-Z][a-zA-Z0-9_]*', 'action' => '[a-zA-Z][a-zA-Z0-9_]*' ), ), ), ), ), ), ) ); @walterdalmut - www.corley.it - www.upcloo.com
    16. 16. ZF2 URI Tunneling - Controller <?php namespace TunnelingRest; The base «AbstractController» is very flexible Use … and enable us to use the «dispatch» action to class Controller extends AbstractController realize what we need in few lines. { public function onDispatch(MvcEvent $e) { $routeMatch = $e->getRouteMatch(); In practice we allocate the model and call the $params = $routeMatch->getParams(); $vars = get_object_vars($e->getRequest()->getQuery()); requested action. The return variable is used as $filter = new ZendFilterFilterChain(); response. $filter->attach(new ZendFilterWordDashToCamelCase()); $filter->attach(new ZendFilterCallback("lcfirst")); $action = $filter->filter($params["action"]); $filter->attach(new ZendFilterCallback("ucfirst")); In case of missing model or missing action an $model = $filter->filter($params["model"]); «InvalidArgumentException» is thrown. $classname = "TunnelingModel{$model}"; if (class_exists($classname)) { $clazz = new $classname; if (property_exists($clazz, $action)) { $ret = call_user_func_array(array($clazz, $action), $vars); $e->setResult($ret); return; } else { throw new InvalidArgumentException("Method "{$action}" doesn't exists'"); } } else { throw new InvalidArgumentException("Class "{$classname}" doesn't exists'"); } } } @walterdalmut - www.corley.it - www.upcloo.com
    17. 17. ZF2 URI Tunneling – Model example <?php namespace TunnelingModel; As you can see, the «model» is a simple class definition. class Menu { public function get($id) { • /tunnel/menu/get?id=1 return array("id" => $id); } • /tunnel/menu/add?x=pizza&y=4 public function add($name, $value) { Very simple implementation return array("name" => $name, "value" => $value); } } @walterdalmut - www.corley.it - www.upcloo.com
    18. 18. ZF2 URI Tunneling – JSON responses <?php namespace Tunneling; Thanks to events we can wire controller output use ZendMvcMvcEvent; to a post processor that converts responses in class Module json messages. { public function onBootstrap($e) { /** @var ZendModuleManagerModuleManager $moduleManager */ • Attach a «postProcess» action and create a $moduleManager = $e->getApplication()->getServiceManager()->get('modulemanager'); /** @var ZendEventManagerSharedEventManager $sharedEvents */ json message. $sharedEvents = $moduleManager->getEventManager()->getSharedManager(); $sharedEvents->attach( 'ZendMvcControllerAbstractController', MvcEvent::EVENT_DISPATCH, array($this, 'postProcess'), -100 ); } //… public function postProcess(MvcEvent $e) { $routeMatch = $e->getRouteMatch(); if (strpos($routeMatch->getMatchedRouteName(), "tunneling") !== false) { $e->getResponse()->setContent(json_encode($e->getResult()->getVariables())); return $e->getResponse(); } } } @walterdalmut - www.corley.it - www.upcloo.com
    19. 19. ZF2 RESTful CRUD modules • ZF2 provides a base controller class that can help us to realize RESTful modules in few steps • ZendMvcControllerAbstractRestfulController • CRUD based implementation (Extended) • get($id) • delete($id) • update($id) • create($id) @walterdalmut - www.corley.it - www.upcloo.com
    20. 20. ZF2 RESTful CRUD module example • Clone ZF2 Skeleton Application • Git clone https://github.com/zendframework/ZendSkeletonApplication.git my-app • Git submodule init • Git submodule update • Clone a ZF2 RESTful module • Git submodule add https://github.com/wdalmut/ZF2-Restful-Module-Skeleton.git module/Main • Add «Main» module into «configs/application.config.php» • Create you application virtual host and try it • http://my-app.local/rest/info/json [getList] • http://my-app.local/rest/info/json/1 [get] • curl –X POST –d ‘hello=world’ http://my-app.local/rest/info [create] • curl –X PUT –d ‘hello=ciao’ http://my-app.local/rest/info/1 [update] • curl –X DELETE http://my-app.local/rest/info/1 [delete] @walterdalmut - www.corley.it - www.upcloo.com
    21. 21. RESTful Controllers <?php • RESTful Controller should extends AbstractRestfulController namespace MainController; • 5 abstract methods (CRUD + List) use ZendMvcControllerAbstractRestfulController; • getList class InfoController extends AbstractRestfulController { • GET operation without parameters public function getList() { • /rest/json/info } return array('ciao' => 'mondo'); • Get public function get($id) • READ resource with parameters (ID) { • /rest/json/info/1 } • Delete public function delete($id) { • DELETE a resource } • Update public function update($id, $data) • UPDATE a resource { • Create } • CREATE a new resource public function create($data = null) { } } @walterdalmut - www.corley.it - www.upcloo.com
    22. 22. First of all play with routes 'router' => array( 'routes' => array( • Create a base route /rest that enable also formatters 'restful' => array( 'type' => 'ZendMvcRouterHttpSegment', • Formatter allow us to switch easly to JSON, 'options' => array( 'route' => '/rest[/:formatter]', XML etc. 'constraints' => array( • Child routes play with controller and identifiers 'formatter' => '[a-zA-Z0-9_-]*', ), ), 'may_terminate' => true, 'child_routes' => array( 'default' => array( 'type' => 'ZendMvcRouterHttpSegment', 'options' => array( 'route' => '[/:controller[/:id]]', 'constraints' => array( 'controller' => '[a-zA-Z][a-zA-Z0-9_-]*', 'id' => '[a-zA-Z0-9_-]*' ), ), ), ), ), ), @walterdalmut - www.corley.it - www.upcloo.com
    23. 23. Formatters • RESTful services can handle different type of messages • JSON • XML • Images • Etc • The high modularity of ZF2 MVC implementation enable us to add different layers of abstractions and formatters is one of this. • Client must know what kind of messages type have to handle. • Post Processors are used to render messages @walterdalmut - www.corley.it - www.upcloo.com
    24. 24. Formatters «configs/module.config.php» 'errors' => array( 'post_processor' => 'json-pp', • The configuration allows us to define different «post processors» 'show_exceptions' => array( 'message' => true, • Errors can be detailed more, for example traces, messages etc. 'trace' => true ) ), 'di' => array( 'instance' => array( 'alias' => array( 'json-pp' => 'MainPostProcessorJson', 'jsonp-pp' => 'MainPostProcessorJsonp', 'image-pp' => 'MainPostProcessorImage' ) ) ), @walterdalmut - www.corley.it - www.upcloo.com
    25. 25. Wiring events (Module.php) /** * @param MvcEvent $e */ public function onBootstrap($e) • Event position -100 { /** @var ZendModuleManagerModuleManager $moduleManager */ • Handle post processors $moduleManager = $e->getApplication()->getServiceManager()->get('modulemanager'); /** @var ZendEventManagerSharedEventManager $sharedEvents */ • Event position 100 $sharedEvents = $moduleManager->getEventManager()->getSharedManager(); • Handle HTTP Method Override $sharedEvents->attach( • Event position 999 'ZendMvcControllerAbstractRestfulController', MvcEvent::EVENT_DISPATCH, • Handle errors array($this, 'postProcess'), -100 ); $sharedEvents->attach( 'MainControllerInfoController', MvcEvent::EVENT_DISPATCH, array($e->getApplication()->getServiceManager()->get('MainHttpRestful'), 'onDispatch'), 100 ); $sharedEvents->attach( 'ZendMvcApplication', MvcEvent::EVENT_DISPATCH_ERROR, array($this, 'errorProcess'), 999 ); } @walterdalmut - www.corley.it - www.upcloo.com
    26. 26. Attach Post Processor to Actions public function postProcess(MvcEvent $e) { $routeMatch = $e->getRouteMatch(); $formatter = $routeMatch->getParam('formatter', false); $di = $e->getTarget()->getServiceLocator()->get('di'); if ($formatter !== false) { if ($e->getResult() instanceof ZendViewModelViewModel) { if (($e->getResult()->getVariables())) { $vars = $e->getResult()->getVariables(); } else { $vars = null; } } else { $vars = $e->getResult(); } $postProcessor = $di->get($formatter . '-pp', array( 'request' => $e->getRequest(), 'response' => $e->getResponse(), 'vars' => $vars, )); $postProcessor->process(); return $postProcessor->getResponse(); } return null; } @walterdalmut - www.corley.it - www.upcloo.com
    27. 27. Example of JSON Post Processor <?php <?php namespace MainPostProcessor; namespace MainPostProcessor; /** abstract class AbstractPostProcessor * { */ protected $_vars = null; class Json extends AbstractPostProcessor private $_request = null; { private $_response = null; public function process() { public function __construct $result = json_encode($this->_vars); (ZendHttpRequest $request, ZendHttpResponse $response, $vars = null) { $headers = $this->getResponse()->getHeaders(); $this->_vars = $vars; $headers->addHeaderLine('Content-Type', 'application/json'); $this->_response = $response; $this->_request = $request; $this->getResponse()->setHeaders($headers); } $this->getResponse()->setContent($result); } public function getResponse() } { return $this->_response; } public function getRequest() { return $this->_request; } abstract public function process(); } @walterdalmut - www.corley.it - www.upcloo.com
    28. 28. ZF2 RESTful Modules Thanks for listening… Any questions? @walterdalmut - www.corley.it - www.upcloo.com

    Editor's Notes

  • Ringrazione l’organizzazione dello ZFDAY, gli sponsor e tutte le persone presenti.
  • Abbiamo solo 30 minuti quindi fare un veloce escursus sui service RESTful e vedremo come realizzare due moduli ZF2.Un primo molto semplice, ispirato a Zend_Rest_Server di ZF1 Un secondo utilizzando un componente integrato nella libreria ZF2
  • Il termite REST è stato coniato nel 2000 da Roy Fielding, uno degli autori del protocollo HTTP, per descrivere un sistema che permette di descrivere ed identificare le risorse web.
  • More Related Content

    Related Books

    Free with a 30 day trial from Scribd

    See all

    ×