<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/">
  <channel>
    <title>Tag: rest :: phly, boy, phly</title>
    <description>Tag: rest :: phly, boy, phly</description>
    <pubDate>Mon, 25 Feb 2013 12:29:00 +0000</pubDate>
    <generator>Zend_Feed_Writer 2.1.4dev (http://framework.zend.com)</generator>
    <link>http://mwop.net/blog/tag/rest.html</link>
    <atom:link rel="self" type="application/rss+xml" href="http://mwop.net/blog/tag/rest-rss.xml"/>
    <item>
      <title>RESTful APIs with ZF2, Part 3</title>
      <pubDate>Mon, 25 Feb 2013 12:29:00 +0000</pubDate>
      <link>http://mwop.net/blog/2013-02-25-restful-apis-with-zf2-part-3.html</link>
      <guid>http://mwop.net/blog/2013-02-25-restful-apis-with-zf2-part-3.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
    In my <a href="/blog/2013-02-11-restful-apis-with-zf2-part-1.html">previous</a> 
    <a href="/blog/2013-02-13-restful-apis-with-zf2-part-2.html">posts</a>, I 
    covered basics of JSON hypermedia APIs using Hypermedia Application Language
    (HAL), and methods for reporting errors, including API-Problem and vnd.error.
</p>

<p>
    In this post, I'll be covering <em>documenting</em> your API -- techniques 
    you can use to indicate what HTTP operations are allowed, as well as convey 
    the full documentation on what endpoints are available, what they accept, 
    and what you can expect them to return.
</p>

<p>
    While I will continue covering general aspects of RESTful APIs in this 
    post, I will also finally introduce several ZF2-specific techniques.
</p><h2>Why Document?</h2>

<p>
    If you're asking this question, you've either never consumed software, or
    your software is perfect and self-documenting. I frankly don't believe 
    either one.
</p>

<p>
    In the case of APIs, those consuming the API need to know how to use it. 
</p>

<ul>
    <li>What endpoints are available? Which operations are available for each endpoint?</li>
    <li>What does each endpoint expect as a payload during the request?</li>
    <li>What can you expect as a payload in return?</li>
    <li>How will errors be communicated?</li>
</ul>

<p>
    While the promise of hypermedia APIs is that each response tells you the
    next steps available, you still, somewhere along the way, need more
    information - what payloads look like, which HTTP verbs should be used,
    and more. If you're <strong>not</strong> documenting your API, you're
    "doing it wrong."
</p>

<h2>Where Should Documentation Live?</h2>

<p>
    This is the much bigger question.
</p>

<p>
    Of the questions I raised above, detailing what should be documented, there
    are two specific types. When discussing what operations are available, 
    we have a technical solution in the form of the <code>OPTIONS</code>
    method and its counterpart, the <code>Allow</code> header. Everything
    else falls under end-user documentation.
</p>

<h2>OPTIONS</h2>

<p>
    The HTTP specification details the <code>OPTIONS</code> method as 
    idempotent, non-cacheable, and for use in detailing what operations
    are available for the given resource specified by the request URI. It
    makes specific mention of the <code>Allow</code> header, but does not
    limit what is returned for requests made via this method.
</p>

<p>
    The <code>Allow</code> header details the allowed HTTP methods for the
    given resource.
</p>

<p>
    Used in combination, you make an <code>OPTIONS</code> request to a URI,
    and it should return a response containing an <code>Allow</code> header;
    from that header value, you then know what other HTTP methods can be made
    to that URI.
</p>

<p>
    What this tells us is that our RESTful endpoint should do the following:
</p>

<ul>
    <li>
        When an <code>OPTIONS</code> request is made, return a response with
        an <code>Allow</code> header that has a list of the available HTTP
        methods allowed.
    </li>

    <li>
        For any HTTP method we do <em>not</em> allow, we should return a
        "405 Not Allowed" response.
    </li>
</ul>

<p>
    These are fairly easy to accomplish in ZF2. <em>(See? I promised I'd
    get to some ZF2 code in this post!)</em>
</p>

<p>
    When creating RESTful endpoints in ZF2, I recommend using
    <code>Zend\Mvc\Controller\AbstractRestfulController</code>. This controller
    contains an <code>options()</code> method which you can use to respond to
    an <code>OPTIONS</code> request. As with any ZF2 controller, returning
    a response object will prevent rendering and bubble out immediately so
    that the response is returned.
</p>

<div class="example"><pre><code language="php">
namespace My\Controller;
use Zend\Mvc\Controller\AbstractRestfulController;

class FooController extends AbstractRestfulController
{
    public function options()
    {
        $response = $this->getResponse();
        $headers  = $response->getHeaders();

        // If you want to vary based on whether this is a collection or an
        // individual item in that collection, check if an identifier from
        // the route is present
        if ($this->params()->fromRoute('id', false)) {
            // Allow viewing, partial updating, replacement, and deletion
            // on individual items
            $headers->addHeaderLine('Allow', implode(',', array(
                'GET',
                'PATCH',
                'PUT',
                'DELETE',
            )));
            return $response;
        }

        // Allow only retrieval and creation on collections
        $headers->addHeaderLine('Allow', implode(',', array(
            'GET',
            'POST',
        )));
        return $response;
    }
}
</code></pre></div>

<p>
    The next trick is returning the 405 response if an invalid option is used.
    For this, you can create a listener in your controller, and wire it to 
    listen at higher-than-default priority. As an example:
</p>

<div class="example"><pre><code language="php">
namespace My\Controller;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\Controller\AbstractRestfulController;

class FooController extends AbstractRestfulController
{
    protected $allowedCollectionMethods = array(
        'GET',
        'POST',
    );

    protected $allowedResourceMethods = array(
        'GET',
        'PATCH',
        'PUT',
        'DELETE',
    );

    public function setEventManager(EventManagerInterface $events)
    {
        parent::setEventManager($events);
        $events->attach('dispatch', array($this, 'checkOptions'), 10);
    }

    public function checkOptions($e)
    {
        $matches  = $e->getRouteMatch();
        $response = $e->getResponse();
        $request  = $e->getRequest();
        $method   = $request->getMethod();

        // test if we matched an individual resource, and then test
        // if we allow the particular request method
        if ($matches->getParam('id', false)) {
            if (!in_array($method, $this->allowedResourceMethods)) {
                $response->setStatusCode(405);
                return $response;
            }
            return;
        }

        // We matched a collection; test if we allow the particular request 
        // method
        if (!in_array($method, $this->allowedCollectionMethods)) {
            $response->setStatusCode(405);
            return $response;
        }
    }
}
</code></pre></div>

<p>
    Note that I moved the allowed methods into properties; if I did the above,
    I'd refactor the <code>options()</code> method to use those properties as
    well to ensure they are kept in sync.
</p>

<p>
    Also note that in the case of an invalid method, I return a response object.
    This ensures that nothing else needs to execute in the controller; I
    discover the problem and return early.
</p>

<h2>End-User Documentation</h2>

<p>
    Now that we have the technical solution out of the way, we're still left 
    with the bulk of the work left to accomplish: providing end-user 
    documentation detailing the various payloads, errors, etc.
</p>

<p>
    I've seen two compelling approaches to this problem. The first builds on
    the <code>OPTIONS</code> method, and the other uses a hypermedia link in
    every response to point to documentation.
</p>

<p>
    The <code>OPTIONS</code> solution is this: <a 
    href="http://zacstewart.com/2012/04/14/http-options-method.html">use the 
    body of an <code>OPTIONS</code> response to provide documentation</a>.
    (Keith Casey <a href="http://vimeo.com/49613738">gave an excellent short 
    presentation about this at REST Fest 2012</a>).
</p>

<p>
    The <code>OPTIONS</code> method allows for you to return a body in the
    response, and also allows for content negotiation. The theory, then, is
    that you return media-type-specific documentation that details the
    methods allowed, and what they specifically accept in the body. While
    there is no standard for this at this time, the first article I linked
    suggested including a description, the parameters expected, and one or more 
    example request bodies for each HTTP method allowed; you'd likely also
    want to detail the responses that can be expected.
</p>

<div class="example"><pre><code language="javascript">
{
    "POST": {
        "description": "Create a new status",
        "parameters": {
            "type": {
                "type": "string",
                "description": "Status type -- text, image, or url; defaults to text",
                "required": false
            },
            "text": {
                "type": "string",
                "description": "Status text; required for text types, optional for others",
                "required": false
            },
            "image_url": {
                "type": "string",
                "description": "URL of image for image types; required for image types",
                "required": false
            },
            "link_url": {
                "type": "string",
                "description": "URL of image for link types; required for link types",
                "required": false
            }
        },
        "responses": [
            {
                "describedBy": "http://example.com/problems/invalid-status",
                "title": "Submitted status was invalid",
                "detail": "Missing text field required for text type"
            },
            {
                "id": "abcdef123456",
                "type": "text",
                "text": "This is a status update",
                "timestamp": "2013-02-22T10:06:05+0:00"
            }
        ],
        "examples": [
            {
                "text": "This is a status update"
            },
            {
                "type": "image",
                "text": "This is the image caption",
                "image_url": "http://example.com/favicon.ico"
            },
            {
                "type": "link",
                "text": "This is a description of the link",
                "link_url": "http://example.com/"
            },
        ]
    }
}
</code></pre></div>

<p>
    If you were to use this methodology, you would alter the 
    <code>options()</code> method such that it does not return a response
    object, but instead return a view model with the documentation.
</p>

<div class="example"><pre><code language="php">
namespace My\Controller;
use Zend\Mvc\Controller\AbstractRestfulController;

class FooController extends AbstractRestfulController
{
    protected $viewModelMap = array(/* ... */);

    public function options()
    {
        $response = $this->getResponse();
        $headers  = $response->getHeaders();

        // Get a view model based on Accept types
        $model    = $this->acceptableViewModelSelector($this->viewModelMap);

        // If you want to vary based on whether this is a collection or an
        // individual item in that collection, check if an identifier from
        // the route is present
        if ($this->params()->fromRoute('id', false)) {
            // Still set the Allow header
            $headers->addHeaderLine('Allow', implode(
                ',', 
                $this->allowedResourceMethods
            ));

            // Set documentation specification as variables
            $model->setVariables($this->getResourceDocumentationSpec());
            return $model;
        }

        // Allow only retrieval and creation on collections
        $headers->addHeaderLine('Allow', implode(
            ',',
            $this->allowedCollectionMethods
        ));
        $model->setVariables($this->getCollectionDocumentationSpec());
        return $model;
    }
}
</code></pre></div>

<p>
    I purposely didn't provide the implementations of the 
    <code>getResourceDocumentationSpec()</code> and 
    <code>getCollectionDocumentationSpec()</code> methods, as that will likely
    be highly specific to your application. Another possibility is to use
    your view engine for this, and specify a template file that has the
    fully-populated information. This would require a custom renderer when
    using JSON or XML, but is a pretty easy solution.
</p>

<p>
    <strong>However, there's one cautionary tale to tell</strong>, something I 
    already mentioned: <code>OPTIONS</code>, per the specification, is 
    <em>non-cacheable</em>.  What this means is that everytime somebody makes an 
    <code>OPTIONS</code> request, any cache control headers you provide will be 
    ignored, which means hitting the server for each and every request to the 
    documentation.  Considering documentation is static, this is problematic; 
    it has even prompted <a href="http://www.mnot.net/blog/2012/10/29/NO_OPTIONS">blog 
    posts urging you not to use OPTIONS for documentation</a>.
</p>

<p>
    Which brings us to the second solution for end-user documentation: a static
    page referenced via a hypermedia link.
</p>

<p>
    This solution is insanely easy: you simply provide a <code>Link</code>
    header in your response, and provide a <code>describedby</code> reference
    pointing to the documentation page:
</p>

<div class="example"><pre><code language="http">
Link: &lt;http://example.com/api/documentation.md&gt;; rel="describedby"
</code></pre></div>

<p>
    With ZF2, this is trivially easy to accomplish: create a route and endpoint
    for your documentation, and then a listener on your controller that adds
    the <code>Link</code> header to your response.
</p>

<p>
    The latter, adding the link header, might look like this:
</p>

<div class="example"><pre><code language="php">
namespace My\Controller;
use Zend\EventManager\EventManagerInterface;
use Zend\Mvc\Controller\AbstractRestfulController;

class FooController extends AbstractRestfulController
{
    public function setEventManager(EventManagerInterface $events)
    {
        parent::setEventManager($events);
        $events->attach('dispatch', array($this, 'injectLinkHeader'), 20);
    }

    public function injectLinkHeader($e)
    {
        $response = $e->getResponse();
        $headers  = $response->getHeaders();
        $headers->addHeaderLine('Link', sprintf(
            '<%s>; rel="describedby"', 
            $this->url('documentation-route-name')
        ));
    }
}
</code></pre></div>

<p>
    If you want to ensure you get a fully qualified URL that includes the 
    schema, hostname, and port, there are a number of ways to do that as
    well; the above gives you the basic idea.
</p>

<p>
    Now, for the route and endpoint, there are tools that will help you
    simplify that task as well, in the form of a couple of ZF2 modules:
    <a href="https://github.com/weierophinney/PhlySimplePage">PhlySimplePage</a>
    and <a href="https://github.com/Soflomo/Prototype">Soflomo\Prototype</a>.
    <em>(Disclosure: I'm the author of PhlySimplePage.)</em>
</p>

<p>
    Both essentially allow you to specify a route and the corresponding
    template name to use, which means all you need to do is provide a little
    configuration, and a view template. <code>Soflomo\Prototype</code> has
    slightly simpler configuration, so I'll demonstrate it here:
</p>

<div class="example"><pre><code language="php">
return array(
    'soflomo_prototype' => array(
        'documentation-route-name' => array(
            'route'    => '/api/documentation',
            'template' => 'api/documentation',
        ),
    ),
    'view_manager' => array(
        'template_map' => array(
            'api/documentation' => __DIR__ . '/../view/api/documentation.phtml',
        ),
    ),
);
</code></pre></div>

<p>
    I personally have been using the <code>Link</code> header solution, as it's
    so simple to implement. It does <em>not</em> write the documentation for you,
    but thinking about it early and implementing it helps ensure you at least
    start writing the documentation, and, if you open source your project,
    you may find you have users who will write the documentation for you if
    they know where it lives.
</p>

<h2>Conclusions</h2>

<p>
    Document your API, or either nobody will use it, or all you're hear are
    complaints from your users about having to guess constantly about how to
    use it. Include the following information:
</p>

<ul>
    <li>What endpoint(s) is (are) available.</li>
    <li>Which operations are available for each endpoint.
        <ul>
            <li>What payloads are expected by the endpoint.</li>
            <li>What payloads can a user expect in return.</li>
            <li>What media types may be used for requests.</li>
            <li>What media types may be expected in responses.</li>
        </ul>
    </li>
</ul>

<p>
    Additionally, make sure that you do the <code>OPTIONS</code>/<code>Allow</code>
    dance; don't just accept any request method, and report the standard
    405 response for methods that you will not allow. Make sure you differentiate
    these for collections versus individual resources, as you likely may
    allow replacing or updating an individual resource, but likely will not
    want to do the same for a whole collection!
</p>

<h2>Next time</h2>

<p>
    So far, I've covered the basics of RESTful JSON APIS, specifically 
    recommending Hypermedia Application Language (HAL) for providing hypermedia
    linking and relations. I've covered error reporting, and provided two
    potential formats (API-Problem and vnd.error) for use with your APIs.
    Now, in this article, I've shown a bit about documenting your API both
    for machine consumption as well as end-users. What's left?
</p>

<p>
    In upcoming parts, I'll talk about ZF2's <code>AbstractRestfulController</code>
    in more detail, as well as how to perform some basic content negotiation.
    I've also had requests about how one might deal with API versioning, and will
    attempt to demonstrate some techniques for doing that as well. Finally,
    expect to see a post showing how I've tied all of this together in a 
    general-purpose ZF2 module so that you can ignore all of these posts and simply
    start writing APIs.
</p>

<h3>Updates</h3>

<p>
    <em>Note: I'll update this post with links to the other posts in the series 
    as I publish them.</em>
</p>

<ul>
    <li><a href="/blog/2013-02-11-restful-apis-with-zf2-part-1">Part 1</a></li>
    <li><a href="/blog/2013-02-13-restful-apis-with-zf2-part-2">Part 2</a></li>
</ul>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>RESTful APIs with ZF2, Part 2</title>
      <pubDate>Wed, 13 Feb 2013 13:40:00 +0000</pubDate>
      <link>http://mwop.net/blog/2013-02-13-restful-apis-with-zf2-part-2.html</link>
      <guid>http://mwop.net/blog/2013-02-13-restful-apis-with-zf2-part-2.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
    In my <a href="/blog/2013-02-11-restful-apis-with-zf2-part-1.html">last post</a>,
    I covered some background on REST and the Richardson Maturity Model, and some
    emerging standards around hypermedia APIs in JSON; in particular, I outlined
    aspects of Hypermedia Application Language (HAL), and how it can be used to
    define a generic structure for JSON resources.
</p>

<p>
    In this post, I cover an aspect of RESTful APIs that's often overlooked:
    reporting problems.
</p><h2>Background</h2>

<p>
    APIs are useful when they're working. But when they fail, they're only 
    useful if they provide us with meaningful information; if all I get is
    a status code, and no indication of what caused the issue, or where I might
    look for more information, I get frustrated.
</p>

<p>
    In consuming APIs, I've come to the following conclusions:
</p>

<ul>
    <li>
        Error conditions need to provide detailed information as to what went 
        wrong, and what steps I may be able to take next. An error code with
        no context gives me nothing to go on.
    </li>

    <li>
        Errors need to be reported consistently. Don't report the error one way
        one time, and another way the next.
    </li>

    <li>
        <strong>DO</strong> use HTTP status codes to indicate an error happened.
        Nothing is more irksome than getting back a 200 status with an error 
        payload.
    </li>

    <li>
        Errors should be reported in a format I have indicated I will Accept 
        (as in the HTTP header). Perhaps the only think more irksome than a 200
        status code for an error is getting back an HTML page when I expect 
        JSON.
    </li>
</ul>

<h2>Why Status Codes Aren't Enough</h2>

<p>
    Since REST leverages and builds on HTTP, an expedient solution for reporting
    problems is to simply use <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP status codes</a>. 
    These are well understood by web developers, right?
</p>

<p>
    <code>4xx</code> error codes are errors made by the requestor, and are actually fairly 
    reasonable to use for reporting things such as lack of authorization tokens,
    incomplete requests, unsupportable operations, or non-supported media types.
</p>

<p>
    But what happens when the error is on the server - because something has
    gone wrong such as inability to reach your persistence layer or credential
    storage? The <code>5xx</code> series of status codes is sparse and wholly unsuited to
    reporting errors of these types -- <em>though you'll likely still want to use
    a <code>500</code> status to report the failure</em>. But what do you present to the consumer
    so that they know whether or not to try again, or what to report to you
    so that you can fix the issue?
</p>

<p>
    A status code simply isn't enough information most of the time. Yes, you 
    want to define standard status codes so that your clients can perform
    reasonable branching, but you also need a way to communicate <em>details</em>
    to the end-user, so that they can log the information for themselves, display
    information to their own end-users, and/or report it back to you so you can
    do something to resolve the situation.
</p>

<h2>Custom Media Types</h2>

<p>
    The first step is to use a custom media type. Media types are typically 
    both a name as well as a structure -- and the latter is what we're after
    when it comes to error reporting. 
</p>

<p>
    If we return a response using this media type, the client then knows how
    to parse it, and can then process it, log it, whatever.
</p>

<p>
    Sure, you can make up your own format -- as long as you are consistent
    in using it, and you document it. But personally, I don't like inventing
    new formats when standard formats exist already. Custom formats mean that 
    custom clients are required for working with the services; using a standard
    format can save effort and time.
</p>

<p>
    In the world of JSON, I've come across two error media types that appear to
    be gaining traction: <code>application/api-problem+json</code> and 
    <code>application/vnd.error+json</code>
</p>

<h3>API-Problem</h3>

<p>
    This particular media type is <a 
    href="http://tools.ietf.org/html/draft-nottingham-http-problem-02">via the 
    IETF</a>. Like HAL, it provides formats in both JSON and XML, making it 
    a nice cross-platform choice.
</p>

<p>
    As noted already, the media type is <code>application/api-problem+json</code>.
    The representation is a single resource, with the following properties:
</p>

<ul>
    <li>
        <strong>describedBy</strong>: a URL to a document describing the error condition (required)
    </li>

    <li>
        <strong>title</strong>: a brief title for the error condition (required)
    </li>

    <li>
        <strong>httpStatus</strong>: the HTTP status code for the current request (optional)
    </li>

    <li>
        <strong>detail</strong>: error details specific to this request (optional)
    </li>

    <li>
        <strong>supportId</strong>: a URL to the specific problem occurrence (e.g., to a log message) (optional)
    </li>
</ul>

<p>
    As an example:
</p>

<div class="example"><pre><code language="http">
HTTP/1.1 500 Internal Error
Content-Type: application/api-problem+json

{
    "describedBy": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
    "detail": "Status failed validation",
    "httpStatus": 500,
    "title": "Internal Server Error"
}
</code></pre></div>

<p>
    The specification allows a large amount of flexibility -- you can have your 
    own custom error types, so long as you have a description of them to link 
    to. You can provide as little or as much detail as you want, and even 
    decide what information to expose based on environment.
</p>

<p>
    I personally like to point to the HTTP status code definitions, and then 
    provide request-specific detail; I find this gives quick and simple results 
    that I can later shape as I add more detail to my API. However, the 
    specification definitely encourages you to have unique error types with 
    discrete URIs that describe them -- never a bad thing when creating APIs.
</p>

<h3>vnd.error</h3>

<p>
    This is a <a href="https://github.com/blongden/vnd.error">proposed media 
    type</a> within the HAL community. Like HAL, it provides formats in both 
    JSON and XML, making it a nice cross-platform choice.
</p>

<p>
    It differentiates from API-Problem in a few ways. First, it allows, and 
    even encourages, reporting collections of errors. If you consider PHP 
    exceptions and the fact that they support "previous" exceptions, this is a 
    powerful concept; you can report the entire chain of errors that led to the 
    response.  Second, it encourages pushing detail out of the web service; 
    errors include a "logRef" property that points to where the error detail lives. 
    This is probably better illustrated than explained.
</p>

<p>
    The response payload is an array of objects. Each object has the following 
    members:
</p>

<ul>
    <li>
        <strong>logRef</strong>: a unique identifier for the specific error which can then be
        used to identify the error within server-side logs (required)
    </li>

    <li>
        <strong>message</strong>: the error message itself (required)
    </li>

    <li>
        <strong>_links</strong>: HAL-compatible links. Typically, "help", "describes", and/or 
        "describedBy" relations will be defined here.
    </li>
</ul>

<p>
    As an example, let's consider the API-Problem example I had earlier, and
    provide a vnd.error equivalent:
</p>

<div class="example"><pre><code language="http">
HTTP/1.1 500 Internal Error
Content-Type: application/vnd.error+json

[
    {
        "logRef": "someSha1HashMostLikely",
        "message": "Status failed validation",
        "_links": {
            "describedBy": {"href": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"}
        }
    }
]
</code></pre></div>

<p>
    vnd.error basically begs you to create custom error types, with documentation 
    end-points that detail the source of the error and what you can do about it 
    (this is true of API-Problem as well).
</p>

<p>
    The requirement to include a log reference ("logRef") and have it be unique 
    can be a stumbling block to implementation, however, as it requires effort 
    for uniquely identifying requests, and logging. However, both the 
    identification and logging can be automated.
</p>

<h2>Summary</h2>

<p>
    Error reporting in APIs is as important as the normal resource payloads 
    themselves. Without good error reporting, when an API raises errors, 
    clients have difficulty understanding what they can do next, and cannot
    provide you, the API provider, with information that will allow you to
    debug on the server side.
</p>

<p>
    As noted at the beginning of the article, if you follow the rules below,
    you'll make consumers of your API happier and more productive.
</p>

<ul>
    <li>
        <strong>DO</strong> use appropriate HTTP status codes to indicate an 
        error happened.
    </li>

    <li>
        Report errors in a format I have indicated I will Accept 
        (as in the HTTP header). 
    </li>
    <li>
        Report errors consistently. Don't report the error one way one time, 
        and another way the next. Standardize on a specific error-reporting 
        media type .  While you <em>can</em> create your own error structure, I 
        recommend using documented, accepted standards. This will make clients 
        more re-usable, and make many of your decisions for you.
    </li>

    <li>
        Provide detailed information as to what went wrong, and what steps I 
        may be able to take next. Provide documentation for each type of error, 
        and link to that documentation from your error payloads.
    </li>

</ul>

<p>
    Which brings me to...
</p>

<h2>Next time</h2>

<p>
    I realize I still haven't covered anything specific to ZF2, but I'll start 
    next time, when I cover the next topic: documenting your API. An 
    undocumented API is a useless API, so it's good to start baking 
    documentation in immediately. I'll survey some of the possibilities and how 
    they can be implemented in ZF2 in the next installment, and then we can get 
    our hands dirty with actual API development.
</p>

<h3>Updates</h3>

<p>
    <em>Note: I'll update this post with links to the other posts in the series 
    as I publish them.</em>
</p>

<ul>
    <li><a href="/blog/2013-02-11-restful-apis-with-zf2-part-1">Part 1</a></li>
    <li><a href="/blog/2013-02-25-restful-apis-with-zf2-part-3">Part 3</a></li>
</ul>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>RESTful APIs with ZF2, Part 1</title>
      <pubDate>Wed, 13 Feb 2013 13:40:00 +0000</pubDate>
      <link>http://mwop.net/blog/2013-02-11-restful-apis-with-zf2-part-1.html</link>
      <guid>http://mwop.net/blog/2013-02-11-restful-apis-with-zf2-part-1.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
    RESTful APIs have been an interest of mine for a couple of years, but due
    to <a href="http://framework.zend.com/blog//zend-framework-2-0-0-stable-released.html">circumstances</a>,
    I've not had much chance to work with them in any meaningful fashion until
    recently.
</p>

<p>
    <a href="http://akrabat.com/">Rob Allen</a> and I proposed a workshop for
    <a href="http://conference.phpbenelux.eu/2013/">PHP Benelux 2013</a> 
    covering RESTful APIs with ZF2. When it was accepted, it gave me the perfect
    opportunity to dive in and start putting the various pieces together.
</p><h2>Background</h2>

<p>
    I've attended any number of conference sessions on API design, read 
    countless articles, and engaged in quite a number of conversations. Three
    facts keep cropping up:
</p>

<ol>
    <li>JSON is fast becoming the preferred exchange format due to the ease 
    with which it de/serializes in almost every language.</li>
    <li>The "holy grail" is <a 
    href="http://martinfowler.com/articles/richardsonMaturityModel.html">Richardson 
    Maturity Model</a> Level 3.</li>
    <li>It's really hard to achieve RMM level 3 with JSON.</li>
</ol>

<h3>Richardson Maturity Model</h3>

<p>
    As a quick review, the Richardson Maturity Model has the following 4 levels:
</p>

<ul>
    <li>Level 0: "The swamp of POX." Basically, a service that uses TCP for 
        transport, primarily as a form of remote procedure call (RPC). 
        Typically, these are not really leveraging HTTP in any meaningful 
        fashion; most systems will use HTTP POST for all interactions. Also, 
        you will often have a single endpoint for all interactions, regardless 
        of whether or not they are strictly related. XML-RPC, SOAP, and 
        JSON-RPC fall under this category.
    </li>

    <li>Level 1: "Resources." In these services, you start breaking the service
        into multiple services, one per "resource," or, in object oriented terms,
        per object. This means a distinct URL per object, which means each
        has its own distinct identity on the web; this often extends not only 
        to the collection of objects, but to individual objects under the 
        collection as well (e.g., "/books" as well as "/books/life-of-pi"). The 
        service may still be RPC in nature, however, and, at this level, often 
        is still using a single HTTP method for all interactions with the 
        resource.
    </li>

    <li>Level 2: "HTTP Verbs." At this level, we start using HTTP verbs with
        our services in the way the HTTP specification intends. GET is for safe 
        operations, and should be cacheable; POST is used for creation and/or 
        updating; DELETE can be used to delete a resource; etc. Rather than 
        doing RPC style methods, we leverage HTTP, occasionally passing 
        additional parameters via the query string or request body.  
        Considerations such as HTTP caching and idempotence are taken into 
        account.
    </li>

    <li>Level 3: "Hypermedia Controls." Building on the previous level, our
        resource representations now also include <em>links</em>, which indicate
        what we can <em>do next</em>. At this level, our API becomes practically
        self-describing; given a single end-point, we should be able to start
        crawling it, using the links in a representation to lead us to the next
        actions.
    </li>
</ul>

<p>
    When I first started playing with web services around a decade ago, 
    everything was stuck at Level 0 or Level 1 -- usually with Level 1 users 
    downgrading to Level 0 because Level 0 offerred consistency and 
    predictability if you chose to use a service type that had a defined 
    envelope format (such as XML-RPC or SOAP).  (I even wrote the XML-RPC 
    server implementation for Zend Framework because I got sick of writing 
    one-off parsers/serializers for custom XML web service implementations.
    When you're implementing many services, predictability is a huge win.)
</p>

<p>
    A few years ago, I started seeing a trend towards Level 2. Web developers
    like the simplicity of using HTTP verbs, as they map very well to <a 
    href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a>
    operations -- the bread and butter of web development. Couple this concept
    with JSON, and it becomes trivially simple to both create a web service, as
    well as consume it.
</p>

<p>
    <em>I'd argue that the majority of web developers are quite happy to be at 
    Level 2 -- and have no problem staying there. They're productive, and the 
    concepts are easy -- both to understand and to implement.</em>
</p>

<p>
    Level 3, though, is where it becomes really interesting. The idea that
    I can examine the represention <em>alone</em> in order to understand what
    I can do next is very intriguing and empowering.
</p>

<h3>JSON and Hypermedia</h3>

<p>
    With XML, hypermedia basically comes for free. Add some &lt;link&gt; 
    elements to your representation, and you're done -- and don't forget the 
    link <code>rel</code>ations!
</p>

<p>
    JSON, however, is another story.
</p>

<p>
    Where do the links go? <em>There is no single, defined way to represent a 
    hyperlink in JSON.</em>
</p>

<p>
    Fortunately, there are some emerging standards. 
</p>

<p>
    First is use of the <a href="http://www.w3.org/wiki/LinkHeader">"Link" HTTP 
    header</a>. While the page I linked shows only a single link in the
    header, you can have multiple links separated by commas. GitHub uses this
    when providing pagination links in their API. Critics will point out that
    the HTTP headers are not technically part of the representation, however;
    strict interpetations of REST and RMM indicate that the hypermedia links
    should be part of the resource representation. Regardless, having the links
    in the HTTP headers is useful for pre-traversal of a service, as you can
    perform HEAD requests only to discover possible actions and workflows.
</p>

<p>
    <a 
    href="http://amundsen.com/media-types/collection/format/">Collection+JSON</a>
    is interesting, as it describes the entire JSON envelope. My one criticism
    is that it details too much; whenever I see a format that dictates how to 
    describe types, I think of XML-RPC or SOAP, and get a little twitchy. It's
    definitely worth a look, though.
</p>

<p>
    What's captured my attention of late, however, is 
    <a href="http://stateless.co/hal_specification.html">Hypertext Application Language</a>,
    or HAL for short. HAL has very few rules, but succinctly describes both how
    to provide hypermedia in JSON as well as how to represent embedded resources
    - the two things that most need standardized structure in JSON. It does this
    while still providing a generic media type, and also describing a mirror 
    image XML format!
</p>

<h3>HAL Media Types</h3>

<p>
    HAL defines two generic media types: <code>application/hal+xml</code> and
    <code>application/hal+json</code>. You will use these as the response
    Content-Type, as they describe the response representation; the client
    can simply request <code>application/json</code>, and the response
    format remains compatible.
</p>

<h3>HAL and Links</h3>

<p>
    HAL provides a very simple structure for JSON hypermedia links. First, all 
    resource representations must contain hypermedia links, and all links are 
    provided in a "_links" object:
</p>

<div class="example"><pre><code language="javascript">
{
    "_links": {
    }
}
</code></pre></div>

<p>
    Second, links are properties of this object. The property name is the link
    relation, and the value is an object containing minimally an "href" 
    property.
</p>

<div class="example"><pre><code language="javascript">
{
    "_links": {
        "self": {"href": "http://example.com/api/status/1234"}
    }
}
</code></pre></div>

<p>
    If a given relation can have multiple links, you provide instead an array
    of objects:
</p>

<div class="example"><pre><code language="javascript">
{
    "_links": {
        "self": {"href": "http://example.com/api/status/1234"},
        "conversation": [
            {"href": "http://example.com/api/status/1237"},
            {"href": "http://example.com/api/status/1241"}
        ]
    }
}
</code></pre></div>

<p>
    Individual links can contain other attributes as desired -- I've seen
    people include the relation again so that it's self-contained in the link 
    object, and it's not uncommon to include a title or name.
</p>

<h3>HAL and Resources</h3>

<p>
    HAL imposes no structure over resources other than requiring the hypermedia 
    links; even then, you typically do not include the hypermedia links when 
    making a request of the web service; the hypermedia links are included only 
    in the representations <em>returned</em> by the service.
</p>

<p>
    So, as an example, you would POST the following:
</p>

<div class="example"><pre><code language="http">
POST /api/status
Host: example.com
Accept: application/json
Content-Type: application/json

{
    "status": "This is my awesome status update!",
    "user": "mwop"
}
</code></pre></div>

<p>
    And from that request, you'd receive the following:
</p>

<div class="example"><pre><code language="http">
201 Created
Location: http://example.com/api/status/1347
Content-Type: application/hal+json

{
    "_links": {
        "self": {"href": "http://example.com/api/status/1347"}
    },
    "id": "1347",
    "timestamp": "2013-02-11 23:33:47",
    "status": "This is my awesome status update!",
    "user": "mwop"
}
</code></pre></div>

<h3>HAL and Embedded Resources</h3>

<p>
    The other important thing that HAL defines is how to <em>embed</em>
    resources. Why is this important? If the resource references other
    resources, you will want to be able to link to them so you can perform
    operations on them, too.
</p>

<p>
    Embedded resources are represented inside an "_embedded" object of the
    representation, and, as resources, contain their own "_links" object as 
    well. Each resource you embed is assigned to a property of that
    object, and if multiple objects of the same type are returned, an array
    of resources is assigned. In fact, this latter is how you represent
    <em>collections</em> in HAL.
</p>

<p>
    Let's consider a simple example first. In previous code samples, I have
    a "user" that's a string; let's make that an embedded resource instead.
</p>

<div class="example"><pre><code language="javascript">
{
    "_links": {
        "self": {"href": "http://example.com/api/status/1347"}
    },
    "id": "1347",
    "timestamp": "2013-02-11 23:33:47",
    "status": "This is my awesome status update!",
    "_embedded": {
        "user": {
            "_links": {
                "self": {"href": "http://example.com/api/user/mwop"}
            }
            "id": "mwop",
            "name": "Matthew Weier O'Phinney",
            "url": "http://mwop.net"
        }
    }
}
</code></pre></div>

<p>
    I've moved the "user" out of the representation, and into the "_embedded"
    object -- because this is where you define embedded resources. Note that
    the "user" is a standard HAL resource itself -- containing hypermedia links.
</p>

<p>
    Now let's look at a collection:
</p>

<div class="example"><pre><code language="javascript">
{
    "_links": {
        "self": {"href": "http://example.com/api/status"},
        "next": {"href": "http://example.com/api/status?page=2"},
        "last": {"href": "http://example.com/api/status?page=100"}
    },
    "count": 2973,
    "per_page": 30,
    "page": 1,
    "_embedded": {
        "status": [
            {
                "_links": {
                    "self": {"href": "http://example.com/api/status/1347"}
                },
                "id": "1347",
                "timestamp": "2013-02-11 23:33:47",
                "status": "This is my awesome status update!",
                "_embedded": {
                    "user": {
                        "_links": {
                            "self": {"href": "http://example.com/api/user/mwop"}
                        }
                        "id": "mwop",
                        "name": "Matthew Weier O'Phinney",
                        "url": "http://mwop.net"
                    }
                }
            }
            /* ... */
        ]
    }
}
</code></pre></div>

<p>
    Note that the "status" property is an array; semantically, all resources
    under this key are of the same type. Also note that the parent resource
    has some additional link relations -- these are related to pagination, and
    allow a client to determine what the next and last pages are (and, if we 
    were midway into the collection, previous and first pages). Since the 
    collection is also a resource, it has some interesting metadata -- how
    many resources are in the collection, how many we represent per page, and
    what the current page is.
</p>

<p>
    Also note that you can nest resources -- simply include an "_embedded" 
    object inside an embedded resource, with additional resources, as I've
    done with the "user" resource inside the status resource shown here. It's 
    turtles all the way down.
</p>

<h2>Next Time</h2>

<p>
    The title of this post indicates I'll be talking about building RESTful 
    APIs with ZF2 -- but so far, I've not said anything about ZF2.
</p>

<p>
    I'll get there. But there's another detour to take: reporting errors.
</p>

<h3>Updates</h3>

<p>
    <em>Note: I'll update this post with links to the other posts in the series 
    as I publish them.</em>
</p>

<ul>
    <li><a href="/blog/2013-02-13-restful-apis-with-zf2-part-2">Part 2</a></li>
    <li><a href="/blog/2013-02-25-restful-apis-with-zf2-part-3">Part 3</a></li>
</ul>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Responding to Different Content Types in RESTful ZF Apps</title>
      <pubDate>Wed, 10 Mar 2010 14:28:22 +0000</pubDate>
      <link>http://mwop.net/blog/233-Responding-to-Different-Content-Types-in-RESTful-ZF-Apps.html</link>
      <guid>http://mwop.net/blog/233-Responding-to-Different-Content-Types-in-RESTful-ZF-Apps.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
    In <a
        href="/matthew/archives/227-Exposing-Service-APIs-via-Zend-Framework.html">previous</a>
    <a
        href="/matthew/archives/228-Building-RESTful-Services-with-Zend-Framework.html">articles</a>,
    I've explored building service endpoints and RESTful services with Zend
    Framework. With RPC-style services, you get to cheat: the protocol dictates
    the content type (XML-RPC uses XML, JSON-RPC uses JSON, SOAP uses XML,
    etc.). With REST, however, you have to make choices: what serialization
    format will you support? 
</p>

<p> 
    Why not support multiple formats?
</p>

<p>
    There's no reason you can't re-use your RESTful web service to support
    multiple formats. Zend Framework and PHP have plenty of tools to assist you
    in responding to different format requests, so don't limit yourself. With a
    small amount of work, you can make your controllers format agnostic, and
    ensure that you respond appropriately to different requests.
</p><h2>Content-Type Detection</h2>

<p>
    The first problem to solve is going to be how to retrieve passed parameters.
    When using XML or JSON as your serialization format, you aren't getting your
    standard POST variables -- you're getting a raw post instead, and you'll
    need to deserialize the payload. In fact, if you're getting a PUT request,
    you also have some work to do, as PHP doesn't do anything with PUT requests.
</p>

<p>
    I do this via an action helper. The basic algorithm is:
</p>

<ul>
    <li>Do we have a raw body in the request? If not, nothing more need be done.</li>
    <li>Determine the Content-Type passed in the request headers, and decode
    appropriately:
    <ul>
        <li>If it was JSON, pass the raw request body to
        <code>json_decode</code> or <code>Zend_Json::decode</code>.</li>
        <li>If it was XML, I pass the raw request body to the
        <code>Zend_Config_XML</code> constructor, and then serialize to an arrya
        using the <code>toArray()</code> method. Yes, it's a hack, but it's
        effective.</li>
        <li>Otherwise, I assume I've got a regular PUT-style request, and I pass
        the data to <code>parse_str()</code>.</li>
    </ul>
    </li>
</ul>

<p>
    I keep the values within the action helper, and then retrieve them on demand
    within my action controller. The helper looks like the following:
</p>

<div class="example"><pre><code lang="php">
class Scrummer_Controller_Helper_Params 
    extends Zend_Controller_Action_Helper_Abstract
{
    /**
     * @var array Parameters detected in raw content body
     */
    protected $_bodyParams = array();

    /**
     * Do detection of content type, and retrieve parameters from raw body if 
     * present
     * 
     * @return void
     */
    public function init()
    {
        $request     = $this-&gt;getRequest();
        $contentType = $request-&gt;getHeader('Content-Type');
        $rawBody     = $request-&gt;getRawBody();
        if (!$rawBody) {
            return;
        }
        switch (true) {
            case (strstr($contentType, 'application/json')):
                $this-&gt;setBodyParams(Zend_Json::decode($rawBody));
                break;
            case (strstr($contentType, 'application/xml')):
                $config = new Zend_Config_Xml($rawBody);
                $this-&gt;setBodyParams($config-&gt;toArray());
                break;
            default:
                if ($request-&gt;isPut()) {
                    parse_str($rawBody, $params);
                    $this-&gt;setBodyParams($params);
                }
                break;
        }
    }

    /**
     * Set body params
     * 
     * @param  array $params 
     * @return Scrummer_Controller_Action
     */
    public function setBodyParams(array $params)
    {
        $this-&gt;_bodyParams = $params;
        return $this;
    }

    /**
     * Retrieve body parameters
     * 
     * @return array
     */
    public function getBodyParams()
    {
        return $this-&gt;_bodyParams;
    }

    /**
     * Get body parameter
     * 
     * @param  string $name 
     * @return mixed
     */
    public function getBodyParam($name)
    {
        if ($this-&gt;hasBodyParam($name)) {
            return $this-&gt;_bodyParams[$name];
        }
        return null;
    }

    /**
     * Is the given body parameter set?
     * 
     * @param  string $name 
     * @return bool
     */
    public function hasBodyParam($name)
    {
        if (isset($this-&gt;_bodyParams[$name])) {
            return true;
        }
        return false;
    }

    /**
     * Do we have any body parameters?
     * 
     * @return bool
     */
    public function hasBodyParams()
    {
        if (!empty($this-&gt;_bodyParams)) {
            return true;
        }
        return false;
    }

    /**
     * Get submit parameters
     * 
     * @return array
     */
    public function getSubmitParams()
    {
        if ($this-&gt;hasBodyParams()) {
            return $this-&gt;getBodyParams();
        }
        return $this-&gt;getRequest()-&gt;getPost();
    }

    public function direct()
    {
        return $this-&gt;getSubmitParams();
    }
}
</code></pre></div>

<p>
    This helper is intended to be run on each request, so I register it in my
    bootstrap:
</p>

<div class="example"><pre><code lang="php">
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    // ...
    protected function _initActionHelpers()
    {
        // ...
        $params = new Scrummer_Controller_Helper_Params();
        Zend_Controller_Action_HelperBroker::addHelper($params);
        // ...
    }
    // ...
}
</code></pre></div>

<p>
    Within your action controller, all you need to do is call the helper:
</p>

<div class="example"><pre><code lang="php">
$data = $this-&gt;params();
</code></pre></div>

<p>
    In a RESTful controller, you'll only need to use this with your
    <code>postAction</code> and <code>putAction</code>. The beauty is that your
    controller can remain ignorant of the Content-Type -- you write the same
    logic to retrieve your parameters regardless.
</p>

<h2>Responding to the client: Context Switching</h2>

<p>
    So, the first half of the problem is taken care of: how to handle the
    request. The second half is responding appropriately.
</p>

<p>
    Zend Framework has some built in tooling to help with this. The
    ContextSwitch and AjaxContext action helpers look for a particular
    parameter -- "format" by default -- and, if detected, will render an
    alternate view script named after the context. As an example, if an "XML"
    context is detected, it will render
    "&lt;controller&gt;/&lt;action&gt;.xml.phtml" -- note the ".xml" segment of
    the script name.
</p>

<p>
    Both helpers work in the same basic way (the latter, AjaxContext, will only
    activate if the request is determined to originate from an XMLHttpRequest):
    you define which actions in the controller are context sensitive, and then
    if the context is detected, a new view script will be used.
</p>

<p>
    So, the first trick is ensuring that the context is passed. As mentioned
    before, the helpers look for a "format" parameter in the request object. You
    can pass this using a query parameter -- "?format=xml" -- but I find that
    ugly. There's an HTTP header defined for this purpose already: "Accept".
</p>

<p>
    Detecting the header and injecting the context into the request is absurdly
    simple, and can be done in a <code>dispatchLoopStartup</code> plugin:
</p>

<div class="example"><pre><code lang="php">
class Scrummer_Controller_Plugin_AcceptHandler
    extends Zend_Controller_Plugin_Abstract
{
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {
        if (!$request instanceof Zend_Controller_Request_Http) {
            return;
        }

        $header = $request-&gt;getHeader('Accept');
        switch (true) {
            case (strstr($header, 'application/json')):
                $request-&gt;setParam('format', 'json');
                break;
            case (strstr($header, 'application/xml') 
                  &amp;&amp; (!strstr($header, 'html'))):
                $request-&gt;setParam('format', 'xml');
                break;
            default:
                break;
        }
    }
}
</code></pre></div>

<p>
    The above can be registered in your application configuration:
</p>

<div class="example"><pre><code lang="ini">
resources.frontController.plugins[] = \&quot;Scrummer_Controller_Plugin_AcceptHandler\&quot;
</code></pre></div>

<p>
    I like my RESTful controllers to automatically expose their methods as
    context-aware. To make this happen, I defined a marker interface,
    "Scrummer_Rest_Controller", and created an action helper that checks if the
    current controller implements it; if it does, I then automatically add
    contexts for the RESTful actions.
</p>

<div class="example"><pre><code lang="php">
class Scrummer_Controller_Helper_RestContexts
    extends Zend_Controller_Action_Helper_Abstract
{
    protected $_contexts = array(
        'xml', 
        'json',
    );

    public function preDispatch()
    {
        $controller = $this-&gt;getActionController();
        if (!$controller instanceof Scrummer_Rest_Controller) {
            return;
        }

        $this-&gt;_initContexts();

        // Set a Vary response header based on the Accept header
        $this-&gt;getResponse()-&gt;setHeader('Vary', 'Accept');
    }

    protected function _initContexts()
    {
        $cs = $this-&gt;getActionController()-&gt;contextSwitch;
        $cs-&gt;setAutoJsonSerialization(false);
        foreach ($this-&gt;_contexts as $context) {
            foreach (array('index', 'post', 'get', 'put', 'delete') as $action) {
                $cs-&gt;addActionContext($action, $context);
            }
        }
        $cs-&gt;initContext();
    }
}
</code></pre></div>

<p>
    Register this via the bootstrap as well:
</p>

<div class="example"><pre><code lang="php">
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
    // ...
    protected function _initActionHelpers()
    {
        // ...
        $params = new Scrummer_Controller_Helper_Params();
        Zend_Controller_Action_HelperBroker::addHelper($params);

        $contexts = new Scrummer_Controller_Helper_RestContexts();
        Zend_Controller_Action_HelperBroker::addHelper($contexts);
        // ...
    }
    // ...
}
</code></pre></div>

<p>
    There are two things to note about this helper. First, you'll see that I
    specify a "Vary" header. This is to ensure that if the client chooses to
    cache responses, it will cache separate responses based on the value sent in
    the "Accept" header.
</p>

<p>
    Second, note that I turn off automatic JSON serialization in the
    ContextSwitch helper. I do this so that I can keep my controller context
    agnostic; this will require additional view scripts, but the ability to keep
    my controller logic simple will be worth it. More on that in a moment.
</p>

<p>
    We now have the infrastructure in place to respond to different contexts
    based on the "Accept" header, and can retrieve parameters appropriately
    based on the "Content-Type" provided us. Now comes the actual response.
</p>

<h2>Responding to the client: Views</h2>

<p>
    Recall that ContextSwitch will attach an additional prefix to the specified
    view script -- "&lt;controller&gt;/&lt;action&gt;.phtml" will become
    "&lt;controller&gt;/&lt;action&gt;.xml.phtml" or
    "&lt;controller&gt;/&lt;action&gt;.json.phtml". Basically, for each context
    we will respond to, we have an additional view script per action.
</p>

<div class="example"><pre><code lang="text">
views/
|-- scripts/
|   `-- foo/
|      |-- delete.phtml
|      |-- delete.json.phtml
|      |-- delete.xml.phtml
|      |-- get.phtml
|      |-- get.json.phtml
|      |-- get.xml.phtml
|      |-- index.phtml
|      |-- index.json.phtml
|      |-- index.xml.phtml
|      |-- post.phtml
|      |-- post.json.phtml
|      |-- post.xml.phtml
|      |-- put.phtml
|      |-- put.json.phtml
|      `-- put.xml.phtml
</code></pre></div>

<p>
    This may seem like overkill, but consider the following representative
    method from my controller:
</p>

<div class="example"><pre><code lang="php">
    public function postAction()
    {
        $data    = $this-&gt;params();
        $service = $this-&gt;getService();
        $result  = $service-&gt;add($data);  
        if (!$result) {
            $this-&gt;view-&gt;form = $service-&gt;getBacklogForm();
            return;
        }

        $this-&gt;view-&gt;success = true;
        $this-&gt;view-&gt;backlog = $result;
    }
</code></pre></div>

<p>
    You don't see anything in there about headers, redirects, or XHR requests.
    Just slinging data to services and views. Real simple.
</p>

<p>
    The view scripts then take care of the appropriate display logic. Let's look
    at two view scripts for the above action, one for plain old HTML, the other
    for a JSON response:
</p>

<div class="example"><pre><code lang="php">
&lt;?php // backlog/post.phtml ?&gt;
&lt;?php 
if ($this-&gt;success):
    $this-&gt;response-&gt;setRedirect($this-&gt;url(array(
        'controller' =&gt; 'backlog',
        'id'         =&gt; $this-&gt;backlog-&gt;id,
    ), 'rest', true));
else: ?&gt;
&lt;h2&gt;Create new backlog&lt;/h2&gt;
&lt;?php
    $this-&gt;form-&gt;setAction($this-&gt;url())
               -&gt;setMethod('post');
    echo $this-&gt;form;
endif ?&gt;

&lt;?php // backlog/post.json.phtml ?&gt;
&lt;?php
if ($this-&gt;success) {
    $url = $this-&gt;url(array(
        'controller' =&gt; 'backlog',
        'id'         =&gt; $this-&gt;backlog-&gt;id,
    ), 'rest', true);
    $this-&gt;response-&gt;setHeader('Location', $url)
                   -&gt;setHttpResponseCode(201);
    echo $this-&gt;json($this-&gt;backlog-&gt;toArray());
    return;
}

$form = $this-&gt;form;
$form-&gt;setAction($this-&gt;url())
     -&gt;setMethod('post');
echo $this-&gt;jsonFormErrors($form);
</code></pre></div>

<p>
    A few things to note: I inject my response object into the view. I feel
    HTTP headers are part of the view, and thus I deal with them there. That
    also serves the purpose of keeping my controllers thin and agnostic.
    Additionally, you'll note that I use different response codes for HTML
    versus JSON -- this allows my JSON-REST support to be RESTful, by returning
    a 201 status code indicating the resource was created; I also return a JSON
    representation of the object. Finally, you'll note that I have a special
    view helper for creating JSON representations of validation errors.
</p>

<h2>Closing points</h2>

<p>
    This post is far from exhaustive, and I expect it will likely raise at least
    as many questions as it tries to answer.
</p>

<p>
    My main point in this article is to get you, the reader and developer,
    thinking creatively about how to expose RESTful web services. Hopefully,
    you're taking the following away:
</p>

<ol>
    <li>Architect in such a way as to minimize the code in your controllers;
    keep that code as agnostic as possible in regards to where input comes from
    and what type of response is required.</li>

    <li>Use front controller plugins and action helpers to create scaffolding
    for your services; these are incredibly flexible and re-usable, and help
    make point 1 that much easier.</li>

    <li>Offload as much as possible to your views. This will allow you to
    isolate logic specific to given formats.</li>
</ol>

<p>
    What are you waiting for? Don't you have an API to expose?
</p>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
    <item>
      <title>Building RESTful Services with Zend Framework</title>
      <pubDate>Wed, 11 Nov 2009 15:38:41 +0000</pubDate>
      <link>http://mwop.net/blog/228-Building-RESTful-Services-with-Zend-Framework.html</link>
      <guid>http://mwop.net/blog/228-Building-RESTful-Services-with-Zend-Framework.html</guid>
      <author>me@mwop.net (Matthew Weier O'Phinney)</author>
      <dc:creator>Matthew Weier O'Phinney</dc:creator>
      <content:encoded><![CDATA[<p>
    As a followup to my <a href="/matthew/archives/227-Exposing-Service-APIs-via-Zend-Framework.html">previous post</a>, I now turn to RESTful web
    services. I originally encountered the term when attending 
    php|tropics in 2005, where <a href="http://twitter.com/g_schlossnagle">George
        Schlossnaggle</a> likened it to simple GET and POST requests. Since
    then, the architectural style -- and developer understanding of the architectural style
    -- has improved a bit, and a more solid definition can be made.
</p><p>
    At its heart, <a
        href="http://en.wikipedia.org/wiki/Representational_State_Transfer"></a>REST
    simply dictates that a given resource have a unique address, and that you
    interact with that resource using HTTP verbs. The standard verbs utilized
    are:
</p>

<ul>
    <li><em>GET</em>: retrieve a list of resources, or, if an identifier is
    present, view a single resource</li>

    <li><em>POST</em>: create a new resource with the data provided in the POST</li>

    <li><em>PUT</em>: update an existing resource as specified by an identifier,
    using the PUT data</li>

    <li><em>DELETE</em>: delete an existing resource as specified by an
    identifier</li>
</ul>

<p>
    The standard URL structure used is as follows:
</p>

<ul>
    <li>"/resource" - GET (list) and POST operations</li>
    <li>"/resource/{identifier}" - GET (view), PUT, and DELETE operations</li>
</ul>

<p>
    What the REST paradigm provides you is a simple, standard way to structure
    your CRUD (Create-Read-Update-Delete) applications. Due to the large number
    of REST clients available, it also means that if you follow the rules, you
    get a ton of interoperability with those clients.
</p>

<p>
    As of <a href="http://framework.zend.com/">Zend Framework</a> 1.9.0, it's
    trivially easy to create RESTful routes for your MVC application, as well as
    to handle the various REST actions via action controllers.
</p>

<p>
    <a
        href="http://framework.zend.com/manual/en/zend.controller.router.html#zend.controller.router.routes.rest">Zend_Rest_Route</a>
    allows you to define RESTful controllers at several levels:
</p>

<ul>
    <li>You can make it the default route, meaning that unless you have
    additional routes, all controllers will be considered REST controllers.</li>

    <li>You can specify modules that contain RESTful controllers.</li>

    <li>You can specify specific controllers per module that are RESTful</li>
</ul>

<p>
    As examples:
</p>

<div class="example"><pre><code lang="php">
$front = Zend_Controller_Front::getInstance();
$router = $front-&gt;getRouter();

// Specifying all controllers as RESTful:
$restRoute = new Zend_Rest_Route($front);
$router-&gt;addRoute('default', $restRoute);

// Specifying the \&quot;api\&quot; module only as RESTful:
$restRoute = new Zend_Rest_Route($front, array(), array(
    'api',
));
$router-&gt;addRoute('rest', $restRoute);

// Specifying the \&quot;api\&quot; module as RESTful, and the \&quot;task\&quot; controller of the
// \&quot;backlog\&quot; module as RESTful:
$restRoute = new Zend_Rest_Route($front, array(), array(
    'api',
    'backlog' =&gt; array('task'),
));
$router-&gt;addRoute('rest', $restRoute);
</code></pre></div>

<p>
    To define a RESTful action controller, you can either extend
    Zend_Rest_Controller, or simply define the following methods in a standard
    controller extending Zend_Controller_Action (you'll need to define them
    regardless):
</p>

<div class="example"><pre><code lang="php">
// Or extend Zend_Rest_Controller
class RestController extends Zend_Controller_Action
{
    // Handle GET and return a list of resources
    public function indexAction() {}

    // Handle GET and return a specific resource item
    public function getAction() {}

    // Handle POST requests to create a new resource item
    public function postAction() {}

    // Handle PUT requests to update a specific resource item
    public function putAction() {}

    // Handle DELETE requests to delete a specific item
    public function deleteAction() {}
}
</code></pre></div>

<p>
    For those methods that operate on individual resources (getAction(),
    putAction(), and deleteAction()), you can test for the identifier using the
    following:
</p>

<div class="example"><pre><code lang="php">
if (!$id = $this-&gt;_getParam('id', false)) {
    // report error, redirect, etc.
}
</code></pre></div>

<h2>Responding is an art</h2>

<p>
    Many developers are either unaware of or ignore the part of the
    specification that dictates what the <em>response</em> should look like.
</p>

<p>
    For instance, in classic REST, after performing a POST to create a new item,
    you should do the following:
</p>

<ul>
    <li>Set the HTTP response code to 201, indicating "Created"</li>

    <li>Set the Location header to point to the canonical URI for the newly
    created item: "/team/31"</li>

    <li>Provide a representation of the newly created item</li>
</ul>

<p>
    Note that there's no redirect, which flies in the face of standard web
    development (where GET-POST-Redirect is the typical format). This is a
    common "gotcha" moment.
</p>

<p>
    Similarly, with PUT requests, you simply indicate an HTTP 200 status when
    successful, and show a representation of the updated item. DELETE requests
    should return an HTTP 204 status (indicating success - no content), with no
    body content.
</p>

<p><em>
    Note: when building RESTful HTML applications, you may want to still do
    GET-POST-Redirect to prevent caching issues. The above applies to RESTful
    web services, which typically use XML or JSON for transactions, and have
    smart clients for interacting with the service.
</em></p>

<p>
    I'll be writing another article soon showing some tips and tricks for
    interacting with HTTP headers, both from the request and for the response,
    as it's a subject lengthy enough for a post of its own. In the meantime,
    start playing with Zend_Rest_Route and standardizing on it for your CRUD
    operations!
</p>]]></content:encoded>
      <slash:comments>0</slash:comments>
    </item>
  </channel>
</rss>
