<?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: http :: phly, boy, phly</title>
    <description>Tag: http :: 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/http.html</link>
    <atom:link rel="self" type="application/rss+xml" href="http://mwop.net/blog/tag/http-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>
  </channel>
</rss>
