build restful zf2 applications - zend · build restful zf2 applications matthew weier o’phinney...
TRANSCRIPT
![Page 1: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/1.jpg)
Build RESTful ZF2 ApplicationsMatthew Weier O’Phinney
@mwophttp://www.mwop.net/
![Page 2: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/2.jpg)
Who I amJust this guy:
• Project Lead, ZendFramework
• Open Source enthusiast• Coffee lover• Chocolate lover• Beer lover
![Page 3: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/3.jpg)
What do I mean by“REST”?
![Page 4: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/4.jpg)
Richardson Maturity Modelhttp://martinfowler.com/articles/richardsonMaturityModel.html
![Page 5: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/5.jpg)
Level 0HTTP to tunnel RPC
![Page 6: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/6.jpg)
Level 1Resources (multiple endpoints)
![Page 7: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/7.jpg)
Level 2HTTP verbs
![Page 8: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/8.jpg)
Level 3Hypermedia Controls
![Page 9: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/9.jpg)
Level 3: Hypermedia Types:Representations// application/vnd.recipes+json{ "id": "identifier", "name": "Recipe name", "ingredients": [ // ingredient objects ], "directions": "Directions for cooking"}
![Page 10: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/10.jpg)
Level 3: Linking{ "_links": { "self": { "href": "http://example.com/api/recipes/1234" }, "describedby": { "href": "http://example.com/api/resources/recipe" } } // ...}
![Page 11: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/11.jpg)
Level 3: Embedding{ "_embedded": { "addresses": [ { "_links": {"self": { "href": "http://example.com/api/addresses/5678" }}, // a representation } ] } // ...}
![Page 12: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/12.jpg)
Aside: HypermediaApplication Language
![Page 13: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/13.jpg)
Which media type should I use?• Vendor-specific? (e.g., application/vnd.myorg.recipe+json)
• Fully generic? (e.g., application/json)
![Page 14: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/14.jpg)
A happy medium: HALapplication/hal+json
• Describes hypermedia links• Describes how to embed resources, either as parts of other
resources or parts of collections• Otherwise retains your object structure
![Page 15: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/15.jpg)
HAL: Resource{ "_links": { "self": { "href": "http://example.com/api/recipes/cacio-e-pepe" } }, "id": "cacio-e-pepe", "name": "Cacio e Pepe Pasta"}
![Page 16: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/16.jpg)
HAL: Embedded resource{ "_links": {"self": {"href": "..."}}, "_embedded": { "author": { "_links": {"self": {"href": "..."}}, "id": "mario", "name": "Mario Mario" } } // ...}
![Page 17: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/17.jpg)
HAL: Collections{ "_links": { "self": {"href": "..."}, "next": {"href": "..."}, "prev": {"href": "..."}, "first": {"href": "..."}, "last": {"href": "..."} }, // ...}
![Page 18: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/18.jpg)
HAL: Collections{ // ... "_embedded": { "recipes": [ { "_links": { "self": { "href": "..." } }, "id": "cacio-e-pepe", "name": "Cacio e Pepe Pasta" }, // ... ] }, "and-other-properties": "if desired"}
![Page 19: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/19.jpg)
Translating theRichardson Maturity
Model to ZF2
![Page 20: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/20.jpg)
Areas of Concern• Routing (unique URLs per resource, link generation)• AbstractRestfulController (HTTP method negotiation)• View Models and Renderers (media-type negotiation and
resource representations)
![Page 21: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/21.jpg)
The easy bit: routing
![Page 22: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/22.jpg)
Segment routesSegment routes with an :id segment:
'recipe' => array( 'type' => 'Segment', 'options' => array( 'route' => '/api/recipes[/:id]', 'defaults' => array( 'controller' => 'Recipe\ApiController', ), ),)
![Page 23: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/23.jpg)
Controllers
![Page 24: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/24.jpg)
AbstractRestfulControllerExtend Zend\Mvc\Controller\AbstractRestfulController
• Provides a method per HTTP method, and calls themaccordingly.
• Extracts the identifier from the route matches and passes itto the method, when available.
• Marshals data from the request and passes it to the method,when available.
![Page 25: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/25.jpg)
Controller methodspublic function create($data); // POST to collectionpublic function delete($id); // DELETE to resourcepublic function deleteList(); // DELETE to collectionpublic function get($id); // GET to resourcepublic function getList(); // GET to collectionpublic function head($id = null); // HEAD to eitherpublic function options(); // OPTIONS to eitherpublic function patch($id, $data); // PATCH to resourcepublic function replaceList($data); // PUT to collectionpublic function update($id, $data); // PUT to resource
![Page 26: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/26.jpg)
Options• You should tell the consumer what HTTP methods are
available for a resource.• You should restrict the consumer to those HTTP methods.• Use the options() method for the first, and write an event
listener for the second.
![Page 27: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/27.jpg)
Example: optionsprotected $collectionOptions = array('GET', 'POST');protected $resourceOptions = array('DELETE', 'GET', 'PATCH', 'PUT');
public function options(){ if ($this->params->fromRoute('id', false)) { $options = $this->resourceOptions; } else { $options = $this->collectionOptions; } $response = $this->getResponse(); $response->getHeaders() ->addHeaderLine('Allow', implode(',', $options)); return $response;}
![Page 28: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/28.jpg)
Example: listener (1)public function setEventManager(EventManagerInterface $events){ $this->events = $events; // Register a listener at high priority $events->attach('dispatch', array($this, 'checkOptions'), 10);}
![Page 29: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/29.jpg)
Example: listener (2)public function checkOptions($e){ if ($this->params->fromRoute('id', false)) { $options = $this->resourceOptions; } else { $options = $this->collectionOptions; } if (in_array($e->getRequest()->getMethod(), $options)) { // HTTP method is allowed! return; } $response = $this->getResponse(); $response->setStatusCode(405); // Method Not Allowed return $response;}
![Page 30: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/30.jpg)
Example: createpublic function create($data){ // if JSON Content-Type, returns decoded data; for // application/x-www-form-urlencoded, returns array $resource = $this->myComposedService->create($data); $response = $this->getResponse(); $response->setStatusCode(201) // Created $response->getHeaders()->addHeaderLine( 'Location', $this->url('recipe', array('id', $resource->id)) ); return $resource; // More on this later}
![Page 31: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/31.jpg)
Media-type negotiation
![Page 32: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/32.jpg)
Media-type negotiation• Choose view model based on Accept header. (Potentially
write custom view models for custom media types.)• Potentially restrict access to specific media types.• Return the appropriate Content-Type in the response.
![Page 33: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/33.jpg)
AcceptableViewModelSelectorSelect view model type based on Accept header.
$criteria = array( 'Zend\View\Model\JsonModel' => array( 'application/json', 'text/json', ),);
$viewModel = $this->acceptableViewModelSelector($criteria);$viewModel->setVariable('resource', $resource);
![Page 34: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/34.jpg)
Use your own view model$criteria = array( 'Recipe\View\RecipeJsonModel' => array( 'application/json', 'text/json', ),);
![Page 35: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/35.jpg)
Raise a 406if (!$viewModel instanceof RecipeJsonModel) { $response = $this->getResponse(); $response->setStatusCode(406); // Not Acceptable return $response;}
![Page 36: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/36.jpg)
Set the Content-Type// in a controller$response = $this->getResponse();$response->getHeaders() ->addHeaderLine('Content-Type', 'application/hal+json');
![Page 37: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/37.jpg)
Set the Content-Type (2)// In a "render" listenerfunction ($e) { $viewModel = $e->getViewModel(); if (!$viewModel instanceof RecipeJsonModel) { return; } $response = $e->getResponse(); $response->getHeaders() ->addHeaderLine('Content-Type', 'application/hal+json');}
![Page 38: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/38.jpg)
Set the Content-Type (3)// In a "response" listener on the View objectfunction ($e) { $viewModel = $e->getModel(); if (!$viewModel instanceof RecipeJsonModel) { return; } $response = $e->getResponse(); $response->getHeaders() ->addHeaderLine('Content-Type', 'application/hal+json');}
![Page 39: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/39.jpg)
Linking
![Page 40: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/40.jpg)
Helpers and plugins• url() controller plugin and view helper• serverUrl() view helper
![Page 41: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/41.jpg)
Url helper// These examples are true of both controllers// and view scripts.
// collection:$this->url('recipe');
// collection with query string:$this->url('recipe', array(), array('query' => true));
// resource:$this->url('recipe', array('id' => $id));
![Page 42: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/42.jpg)
ServerUrl helper// Generates fully qualified URL (vs. just path)$this->serverUrl($urlGeneratedViaHelper);
![Page 43: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/43.jpg)
Renderers
![Page 44: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/44.jpg)
Resource representations• The “R” in REST is for “Representational”• The root of “representational” is “presentation”• The View layer is where presentation is achieved
![Page 45: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/45.jpg)
Approaches• Custom View Models• Custom Renderers
![Page 46: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/46.jpg)
Extending JsonModel• Provides a serialize() method, which is called by theJsonRenderer
• Allows you to marshal what you want into the structure youwant for the representation
![Page 47: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/47.jpg)
Example: view modelclass RecipeJsonModel extends JsonModel{ public function serialize() { $resource = $this->getVariable('resource'); $representation = array( 'id' => $resource->getId(), 'name' => $resource->getName(), ); return Json::encode($representation); }}
![Page 48: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/48.jpg)
Custom renderer• Can provide helper capabilities (e.g., for links!).• Usually managed by the ServiceManager, allowing for
dependencies.• Can alter workflow based on view models detected, or
contents of view model.
![Page 49: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/49.jpg)
Example: rendererclass RecipeJsonRenderer implements RendererInterface{ public function render($nameOrModel, $values = null) { if ($nameOrModel instanceof RecipeJsonModel) { $helper = $this->helpers->get('RenderRecipe'); } elseif ($nameOrModel instanceof RecipesJsonModel) { $helper = $this->helpers->get('RenderRecipes'); } else { throw new Exception('Cannot handle this!'); } // delegate to the selected helper! return $helper($nameOrModel); }}
![Page 50: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/50.jpg)
Recap
![Page 51: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/51.jpg)
Understand the RichardsonMaturity Modelhttp://martinfowler.com/articles/richardsonMaturityModel.html
• Level 0: RPC, POX• Level 1: Resources• Level 2: HTTP verbs• Level 3: Hypermedia controls
![Page 52: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/52.jpg)
Get to know emerging RESTstandards
• Hypermedia Application Language(http://tools.ietf.org/html/draft-kelly-json-hal-05)
• Collection JSON(http://amundsen.com/media-types/collection/)
![Page 53: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/53.jpg)
Understand the HTTPspecificationhttp://www.w3.org/Protocols/rfc2616/rfc2616.html
• HTTP methods, which are idempotent, and expectedresponse structure
• Accept and Content-Type headers, and how they relate• HTTP response status codes
![Page 54: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/54.jpg)
Understand ZF2’s HTTPcapabilities
• Request, Response, and Headers objects from Zend\Http• AcceptableViewModelSelector MVC controller helper and theAccept HTTP header
![Page 55: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/55.jpg)
Utilize ZF2’s event system• Use event listeners to check for Content-Type, HTTP method
used, Accept header, etc., and return early for bad requests• Use event listeners to shape the rendering cycle; use a
combination of application and view events
![Page 56: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/56.jpg)
Utilize ZF2’s view layer• Use custom view models to “type” your responses• Use custom view renderers to ensure you return appropriate
representations• Use existing helpers such as url() and serverUrl() to
generate links• Create new helpers for implementing link relations
![Page 57: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/57.jpg)
Topics not covered• API versioning (hint: use custom media types and/or headers)• Authentication/Authorization (hint: use OAuth tokens)• XML and XML formats (hint: PHP has lots of tools for this)• Probably tons more…
![Page 58: Build RESTful ZF2 Applications - Zend · Build RESTful ZF2 Applications Matthew Weier O’Phinney @mwop](https://reader031.vdocument.in/reader031/viewer/2022013113/5b5a9f977f8b9aa30c8c72ae/html5/thumbnails/58.jpg)
Thank You@mwop
http://www.mwop.net/http://framework.zend.com/