<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title type="text">Blog entries tagged zf2 :: mwop.net</title>
  <updated>2014-03-26T15:30:00-05:00</updated>
  <generator uri="https://getlaminas.org" version="2">Laminas_Feed_Writer</generator>
  <link rel="alternate" type="text/html" href="https://mwop.net/blog/tag/zf2"/>
  <link rel="self" type="application/atom+xml" href="https://mwop.net/blog/tag/zf2/atom.xml"/>
  <id>https://mwop.net/blog/tag/zf2</id>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Apigility: Using RPC with HAL]]></title>
    <published>2014-03-26T15:30:00-05:00</published>
    <updated>2014-03-26T15:30:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2014-03-26-apigility-rpc-with-hal.html"/>
    <id>https://mwop.net/blog/2014-03-26-apigility-rpc-with-hal.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>A few days ago, we <xhtml:a href="http://bit.ly/ag-1-beta1">released
our first beta of Apigility</xhtml:a>. We've started our documentation
effort now, and one question has arisen a few times that I want to
address: How can you use Hypermedia Application Language (HAL) in
RPC services?</xhtml:p>
<xhtml:h2>HAL?</xhtml:h2>
<xhtml:p><xhtml:a href="http://tools.ietf.org/html/draft-kelly-json-hal-06">Hypermedia
Application Language</xhtml:a> is an IETF proposal for how to represent
resources and their relations within APIs. Technically, it provides
two mediatypes, <xhtml:code>application/hal+json</xhtml:code> and
<xhtml:code>application/hal+xml</xhtml:code>; however, Apigility only provides
the JSON variant.</xhtml:p>
<xhtml:p>The important things to know about HAL are:</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>It provides a standard way of describing relational links. All
relational links are under a <xhtml:code>_links</xhtml:code> property of the
resource. That property is an object. Each property of that object
is a link relation; the value of each link relation is an object
(or array of such objects) describing the link that must minimally
contain an <xhtml:code>href</xhtml:code> proerty. The link object itself can
contain some additional metadata, such as a mediatype, a name
(useful for differentiating between multiple link objects assigned
to the same relation).</xhtml:p>
<xhtml:p>While not required, the specification recommends resources
contain a "self" relational link, indicating the canonical location
for the resource. This is particularly useful when we consider
embedding (the next topic).</xhtml:p>
<xhtml:p>Sound hard? It's not:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
        <xhtml:span class="hljs-string">"self"</xhtml:span>: {
            <xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"/blog/2014-03-26-apigility-rpc-with-hal"</xhtml:span>
        }
    }
}
</xhtml:code></xhtml:pre></xhtml:li>
<xhtml:li>
<xhtml:p>Besides link relations, HAL also provides a standard way of
describing <xhtml:em>embedded resources</xhtml:em>. An embedded resource is any
other resource you can address via your API, and, as such, would be
structured as a HAL resource — in other words, it would have a
<xhtml:code>_links</xhtml:code> property with relational links. Essentially,
any property of the resource you're returning that can itself be
addressed via the URI must be <xhtml:em>embedded</xhtml:em> in the resource.
This is done via the property <xhtml:code>_embedded</xhtml:code>.</xhtml:p>
<xhtml:p>Like <xhtml:code>_links</xhtml:code>, <xhtml:code>_embedded</xhtml:code> is an object.
Each key in the object is the local name by which the resource
refers to the embedded resource. The value of such keys can either
be HAL resources or <xhtml:em>arrays</xhtml:em> of HAL resources; in fact, this
is how <xhtml:em>collections</xhtml:em> are represented in HAL!</xhtml:p>
<xhtml:p>As examples:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
        <xhtml:span class="hljs-string">"self"</xhtml:span>: {
            <xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"/blog/2014-03-26-apigility-rpc-with-hal"</xhtml:span>
        }
    },
    <xhtml:span class="hljs-string">"_embedded"</xhtml:span>: {
        <xhtml:span class="hljs-string">"author"</xhtml:span>: {
            <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
                <xhtml:span class="hljs-string">"self"</xhtml:span>: {
                    <xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"/blog/author/matthew"</xhtml:span>
                }
            },
            <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"matthew"</xhtml:span>,
            <xhtml:span class="hljs-string">"name"</xhtml:span>: <xhtml:span class="hljs-string">"Matthew Weier O'Phinney"</xhtml:span>,
            <xhtml:span class="hljs-string">"url"</xhtml:span>: <xhtml:span class="hljs-string">"http://mwop.net"</xhtml:span>
        },
        <xhtml:span class="hljs-string">"tags"</xhtml:span>: [
            {
                <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
                    <xhtml:span class="hljs-string">"self"</xhtml:span>: {
                        <xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"/blog/tag/php"</xhtml:span>
                    }
                },
                <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"php"</xhtml:span>
            },
            {
                <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
                    <xhtml:span class="hljs-string">"self"</xhtml:span>: {
                        <xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"/blog/tag/rest"</xhtml:span>
                    }
                },
                <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"rest"</xhtml:span>
            }
        ]
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>The example above shows two embedded resources. The first is the
author; the second, a collection of tags. Note that <xhtml:em>every</xhtml:em>
object under <xhtml:code>_embedded</xhtml:code> is a HAL object!</xhtml:p>
<xhtml:p>You can go quite far with this — you can also have embedded
resources inside your embedded resources, arbitrarily deep.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:h2>RPC?</xhtml:h2>
<xhtml:p>RPC stands for Remote Procedure Call, and, when describing a web
API, is usually used to describe a web service that publishes
multiple method calls at a single URI using only <xhtml:code>POST</xhtml:code>;
XML-RPC and SOAP are the usual suspects.</xhtml:p>
<xhtml:p>In Apigility, we use the term RPC in a much looser sense; we use
it to describe one-off services: actions like "authenticate," or
"notify," or "register" would all make sense here. They are actions
that usually only need to respond to a single HTTP method, and
which may or may not describe a "thing", which is what we usually
consider a "resource" when discussing REST terminology.</xhtml:p>
<xhtml:p>That said: what if what we want to return from the RPC call
<xhtml:em>are</xhtml:em> REST resources?</xhtml:p>
<xhtml:h2>Returning HAL from RPC Services</xhtml:h2>
<xhtml:p>In order to return HAL from RPC services, we need to understand
(a) how Content Negotiation works, and (b) what needs to be
returned in order for the HAL renderer to be able to create a
representation.</xhtml:p>
<xhtml:p>For purposes of this example, I'm positing a
<xhtml:code>RegisterController</xhtml:code> as an RPC service that, on success,
is returning a <xhtml:code>User</xhtml:code> object that I want rendered as a
HAL resource.</xhtml:p>
<xhtml:p>The <xhtml:a href="https://github.com/zfcampus/zf-content-negotiation">zf-content-negotiation</xhtml:a>
module takes care of content negotiation for Apigility. It
introspects the <xhtml:code>Accept</xhtml:code> header in order to determine if
we can return a representation, and then, if it can, will cast any
<xhtml:code>ZF\ContentNegotiation\ViewModel</xhtml:code> returned from a
controller to the appropriate view model for the representation.
From there, a renderer will pick up the view model and do what
needs to be done.</xhtml:p>
<xhtml:p>So, the first thing we have to do is return
<xhtml:code>ZF\ContentNegotiation\ViewModel</xhtml:code> instances from our
controller.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractActionController</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">ZF</xhtml:span>\<xhtml:span class="hljs-title">ContentNegotiation</xhtml:span>\<xhtml:span class="hljs-title">ViewModel</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">RegisterController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractActionController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">registerAction</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-comment">/* ... do some work ... get a user ... */</xhtml:span>
        <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> ViewModel(<xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-string">'user'</xhtml:span> =&gt; $user));
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>The <xhtml:a href="https://github.com/zfcampus/zf-hal">zf-hal</xhtml:a>
module in Apigility creates the actual HAL representations.
<xhtml:code>zf-hal</xhtml:code> looks for a "payload" variable in the view
model, and expects that value to be either a
<xhtml:code>ZF\Hal\Entity</xhtml:code> (single item) or
<xhtml:code>ZF\Hal\Collection</xhtml:code>. When creating an
<xhtml:code>Entity</xhtml:code> object, you need the object being represented,
as well as the identifier. So, let's update our return value.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractActionController</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">ZF</xhtml:span>\<xhtml:span class="hljs-title">ContentNegotiation</xhtml:span>\<xhtml:span class="hljs-title">ViewModel</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">ZF</xhtml:span>\<xhtml:span class="hljs-title">Hal</xhtml:span>\<xhtml:span class="hljs-title">Entity</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">RegisterController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractActionController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">registerAction</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-comment">/* ... do some work
         * ... get a $user
         * ... assume we have also now have an $id
         */</xhtml:span>
        <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">new</xhtml:span> ViewModel(<xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-string">'payload'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'user'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">new</xhtml:span> Entity($user, $id),
        )));
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p><xhtml:code>zf-hal</xhtml:code> contains what's called a "metadata map".
This is a map of classes to information on how <xhtml:code>zf-hal</xhtml:code>
should render them: what route to use, what additional relational
links to inject, how to serialize the object, what field represents
the identifier, etc.</xhtml:p>
<xhtml:p>In most cases, you will have likely already defined a REST
service for the resource you want to return from the RPC service,
in which case you will be done. However, if you want, you can go in
and manually configure the metadata map in your API module's
<xhtml:code>config/module.config.php</xhtml:code> file:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">array</xhtml:span>(
    <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
    <xhtml:span class="hljs-string">'zf-hal'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'metadata_map'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'User'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                <xhtml:span class="hljs-string">'route_name'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'api.rest.user'</xhtml:span>,
                <xhtml:span class="hljs-string">'entity_identifier_name'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'username'</xhtml:span>,
                <xhtml:span class="hljs-string">'route_identifier_name'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'user_id'</xhtml:span>,
                <xhtml:span class="hljs-string">'hydrator'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'Zend\Stdlib\Hydrator\ObjectProperty'</xhtml:span>,
            ),
        ),
    ),
);
</xhtml:code></xhtml:pre>
<xhtml:p>Finally, we need to make sure that the service is configured to
actually return HAL. We can do this in the admin if we want. Find
the "Content Negotiation" section of the admin, and the "Content
Negotiation Selector" item, and set that to "HalJson"; don't forget
to save! Alternately, you can do this manually in the API module's
<xhtml:code>config/module.config.php</xhtml:code> file, under the
<xhtml:code>zf-content-negotiation</xhtml:code> section:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">array</xhtml:span>(
    <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
    <xhtml:span class="hljs-string">'zf-content-negotiation'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'controllers'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
            <xhtml:span class="hljs-string">'RegisterController'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'HalJson'</xhtml:span>,
        ),
        <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
    ),
);
</xhtml:code></xhtml:pre>
<xhtml:p>Once your changes are complete, when you make a successful
request to the URI for your "register" RPC service, you'll receive
a HAL response pointing to the canonical URI for the user resource
created!</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2014-03-26-apigility-rpc-with-hal.html">Apigility:
Using RPC with HAL</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2014-03-26T15:30:00-05:00">26 March
2014</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[RESTful APIs with ZF2, Part 3]]></title>
    <published>2013-02-25T06:29:00-06:00</published>
    <updated>2013-02-25T06:29:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2013-02-25-restful-apis-with-zf2-part-3.html"/>
    <id>https://mwop.net/blog/2013-02-25-restful-apis-with-zf2-part-3.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>In my <xhtml:a href="/blog/2013-02-11-restful-apis-with-zf2-part-1.html">previous</xhtml:a>
<xhtml:a href="/blog/2013-02-13-restful-apis-with-zf2-part-2.html">posts</xhtml:a>, I
covered basics of JSON hypermedia APIs using Hypermedia Application
Language (HAL), and methods for reporting errors, including
API-Problem and <xhtml:code>vnd.error</xhtml:code>.</xhtml:p>
<xhtml:p>In this post, I'll be covering <xhtml:em>documenting</xhtml: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.</xhtml:p>
<xhtml:p>While I will continue covering general aspects of RESTful APIs
in this post, I will also finally introduce several ZF2-specific
techniques.</xhtml:p>
<xhtml:h2>Why Document?</xhtml:h2>
<xhtml: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.</xhtml:p>
<xhtml:p>In the case of APIs, those consuming the API need to know how to
use it.</xhtml:p>
<xhtml:ul>
<xhtml:li>What endpoints are available? Which operations are available
for each endpoint?</xhtml:li>
<xhtml:li>What does each endpoint expect as a payload during the
request?</xhtml:li>
<xhtml:li>What can you expect as a payload in return?</xhtml:li>
<xhtml:li>How will errors be communicated?</xhtml:li>
</xhtml:ul>
<xhtml: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 <xhtml:strong>not</xhtml:strong>
documenting your API, you're "doing it wrong."</xhtml:p>
<xhtml:h2>Where Should Documentation Live?</xhtml:h2>
<xhtml:p>This is the much bigger question.</xhtml:p>
<xhtml: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 <xhtml:code>OPTIONS</xhtml:code> method and its counterpart, the
<xhtml:code>Allow</xhtml:code> header. Everything else falls under end-user
documentation.</xhtml:p>
<xhtml:h2>OPTIONS</xhtml:h2>
<xhtml:p>The HTTP specification details the <xhtml:code>OPTIONS</xhtml: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 <xhtml:code>Allow</xhtml:code>
header, but does not limit what is returned for requests made via
this method.</xhtml:p>
<xhtml:p>The <xhtml:code>Allow</xhtml:code> header details the allowed HTTP methods
for the given resource.</xhtml:p>
<xhtml:p>Used in combination, you make an <xhtml:code>OPTIONS</xhtml:code> request to
a URI, and it should return a response containing an
<xhtml:code>Allow</xhtml:code> header; from that header value, you then know
what other HTTP methods can be made to that URI.</xhtml:p>
<xhtml:p>What this tells us is that our RESTful endpoint should do the
following:</xhtml:p>
<xhtml:ul>
<xhtml:li>When an <xhtml:code>OPTIONS</xhtml:code> request is made, return a response
with an <xhtml:code>Allow</xhtml:code> header that has a list of the available
HTTP methods allowed.</xhtml:li>
<xhtml:li>For any HTTP method we do <xhtml:em>not</xhtml:em> allow, we should return
a "405 Not Allowed" response.</xhtml:li>
</xhtml:ul>
<xhtml:p>These are fairly easy to accomplish in ZF2. <xhtml:em>(See? I promised
I'd get to some ZF2 code in this post!)</xhtml:em></xhtml:p>
<xhtml:p>When creating RESTful endpoints in ZF2, I recommend using
<xhtml:code>Zend\Mvc\Controller\AbstractRestfulController</xhtml:code>. This
controller contains an <xhtml:code>options()</xhtml:code> method which you can
use to respond to an <xhtml:code>OPTIONS</xhtml:code> request. As with any ZF2
controller, returning a response object will prevent rendering and
bubble out immediately so that the response is returned.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">My</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">FooController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">options</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span>
    </xhtml:span>{
        $response = <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;getResponse();
        $headers  = $response-&gt;getHeaders();

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

        <xhtml:span class="hljs-comment">// Allow only retrieval and creation on collections</xhtml:span>
        $headers-&gt;addHeaderLine(<xhtml:span class="hljs-string">'Allow'</xhtml:span>, implode(<xhtml:span class="hljs-string">','</xhtml:span>, <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'GET'</xhtml:span>,
            <xhtml:span class="hljs-string">'POST'</xhtml:span>,
        )));
        <xhtml:span class="hljs-keyword">return</xhtml:span> $response;
    }
}
</xhtml:code></xhtml:pre>
<xhtml: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:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">My</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">EventManager</xhtml:span>\<xhtml:span class="hljs-title">EventManagerInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">FooController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">protected</xhtml:span> $allowedCollectionMethods = <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'GET'</xhtml:span>,
        <xhtml:span class="hljs-string">'POST'</xhtml:span>,
    );

    <xhtml:span class="hljs-keyword">protected</xhtml:span> $allowedResourceMethods = <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'GET'</xhtml:span>,
        <xhtml:span class="hljs-string">'PATCH'</xhtml:span>,
        <xhtml:span class="hljs-string">'PUT'</xhtml:span>,
        <xhtml:span class="hljs-string">'DELETE'</xhtml:span>,
    );

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">setEventManager</xhtml:span><xhtml:span class="hljs-params">(EventManagerInterface $events)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">parent</xhtml:span>::setEventManager($events);
        $events-&gt;attach(<xhtml:span class="hljs-string">'dispatch'</xhtml:span>, <xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-keyword">$this</xhtml:span>, <xhtml:span class="hljs-string">'checkOptions'</xhtml:span>), <xhtml:span class="hljs-number">10</xhtml:span>);
    }

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">checkOptions</xhtml:span><xhtml:span class="hljs-params">($e)</xhtml:span>
    </xhtml:span>{
        $matches  = $e-&gt;getRouteMatch();
        $response = $e-&gt;getResponse();
        $request  = $e-&gt;getRequest();
        $method   = $request-&gt;getMethod();

        <xhtml:span class="hljs-comment">// test if we matched an individual resource, and then test</xhtml:span>
        <xhtml:span class="hljs-comment">// if we allow the particular request method</xhtml:span>
        <xhtml:span class="hljs-keyword">if</xhtml:span> ($matches-&gt;getParam(<xhtml:span class="hljs-string">'id'</xhtml:span>, <xhtml:span class="hljs-keyword">false</xhtml:span>)) {
            <xhtml:span class="hljs-keyword">if</xhtml:span> (!in_array($method, <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;allowedResourceMethods)) {
                $response-&gt;setStatusCode(<xhtml:span class="hljs-number">405</xhtml:span>);
                <xhtml:span class="hljs-keyword">return</xhtml:span> $response;
            }
            <xhtml:span class="hljs-keyword">return</xhtml:span>;
        }

        <xhtml:span class="hljs-comment">// We matched a collection; test if we allow the particular request </xhtml:span>
        <xhtml:span class="hljs-comment">// method</xhtml:span>
        <xhtml:span class="hljs-keyword">if</xhtml:span> (!in_array($method, <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;allowedCollectionMethods)) {
            $response-&gt;setStatusCode(<xhtml:span class="hljs-number">405</xhtml:span>);
            <xhtml:span class="hljs-keyword">return</xhtml:span> $response;
        }
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>Note that I moved the allowed methods into properties; if I did
the above, I'd refactor the <xhtml:code>options()</xhtml:code> method to use
those properties as well to ensure they are kept in sync.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:h2>End-User Documentation</xhtml:h2>
<xhtml: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.</xhtml:p>
<xhtml:p>I've seen two compelling approaches to this problem. The first
builds on the <xhtml:code>OPTIONS</xhtml:code> method, and the other uses a
hypermedia link in every response to point to documentation.</xhtml:p>
<xhtml:p>The <xhtml:code>OPTIONS</xhtml:code> solution is this: <xhtml:a href="http://zacstewart.com/2012/04/14/http-options-method.html">use the
body of an <xhtml:code>OPTIONS</xhtml:code> response to provide
documentation</xhtml:a>. (Keith Casey <xhtml:a href="https://vimeo.com/49613738">gave an excellent short presentation
about this at REST Fest 2012</xhtml:a>).</xhtml:p>
<xhtml:p>The <xhtml:code>OPTIONS</xhtml: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.</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"POST"</xhtml:span>: {
        <xhtml:span class="hljs-string">"description"</xhtml:span>: <xhtml:span class="hljs-string">"Create a new status"</xhtml:span>,
        <xhtml:span class="hljs-string">"parameters"</xhtml:span>: {
            <xhtml:span class="hljs-string">"type"</xhtml:span>: {
                <xhtml:span class="hljs-string">"type"</xhtml:span>: <xhtml:span class="hljs-string">"string"</xhtml:span>,
                <xhtml:span class="hljs-string">"description"</xhtml:span>: <xhtml:span class="hljs-string">"Status type -- text, image, or url; defaults to text"</xhtml:span>,
                <xhtml:span class="hljs-string">"required"</xhtml:span>: <xhtml:span class="hljs-literal">false</xhtml:span>
            },
            <xhtml:span class="hljs-string">"text"</xhtml:span>: {
                <xhtml:span class="hljs-string">"type"</xhtml:span>: <xhtml:span class="hljs-string">"string"</xhtml:span>,
                <xhtml:span class="hljs-string">"description"</xhtml:span>: <xhtml:span class="hljs-string">"Status text; required for text types, optional for others"</xhtml:span>,
                <xhtml:span class="hljs-string">"required"</xhtml:span>: <xhtml:span class="hljs-literal">false</xhtml:span>
            },
            <xhtml:span class="hljs-string">"image_url"</xhtml:span>: {
                <xhtml:span class="hljs-string">"type"</xhtml:span>: <xhtml:span class="hljs-string">"string"</xhtml:span>,
                <xhtml:span class="hljs-string">"description"</xhtml:span>: <xhtml:span class="hljs-string">"URL of image for image types; required for image types"</xhtml:span>,
                <xhtml:span class="hljs-string">"required"</xhtml:span>: <xhtml:span class="hljs-literal">false</xhtml:span>
            },
            <xhtml:span class="hljs-string">"link_url"</xhtml:span>: {
                <xhtml:span class="hljs-string">"type"</xhtml:span>: <xhtml:span class="hljs-string">"string"</xhtml:span>,
                <xhtml:span class="hljs-string">"description"</xhtml:span>: <xhtml:span class="hljs-string">"URL of image for link types; required for link types"</xhtml:span>,
                <xhtml:span class="hljs-string">"required"</xhtml:span>: <xhtml:span class="hljs-literal">false</xhtml:span>
            }
        },
        <xhtml:span class="hljs-string">"responses"</xhtml:span>: [
            {
                <xhtml:span class="hljs-string">"describedBy"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/problems/invalid-status"</xhtml:span>,
                <xhtml:span class="hljs-string">"title"</xhtml:span>: <xhtml:span class="hljs-string">"Submitted status was invalid"</xhtml:span>,
                <xhtml:span class="hljs-string">"detail"</xhtml:span>: <xhtml:span class="hljs-string">"Missing text field required for text type"</xhtml:span>
            },
            {
                <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"abcdef123456"</xhtml:span>,
                <xhtml:span class="hljs-string">"type"</xhtml:span>: <xhtml:span class="hljs-string">"text"</xhtml:span>,
                <xhtml:span class="hljs-string">"text"</xhtml:span>: <xhtml:span class="hljs-string">"This is a status update"</xhtml:span>,
                <xhtml:span class="hljs-string">"timestamp"</xhtml:span>: <xhtml:span class="hljs-string">"2013-02-22T10:06:05+0:00"</xhtml:span>
            }
        ],
        <xhtml:span class="hljs-string">"examples"</xhtml:span>: [
            {
                <xhtml:span class="hljs-string">"text"</xhtml:span>: <xhtml:span class="hljs-string">"This is a status update"</xhtml:span>
            },
            {
                <xhtml:span class="hljs-string">"type"</xhtml:span>: <xhtml:span class="hljs-string">"image"</xhtml:span>,
                <xhtml:span class="hljs-string">"text"</xhtml:span>: <xhtml:span class="hljs-string">"This is the image caption"</xhtml:span>,
                <xhtml:span class="hljs-string">"image_url"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/favicon.ico"</xhtml:span>
            },
            {
                <xhtml:span class="hljs-string">"type"</xhtml:span>: <xhtml:span class="hljs-string">"link"</xhtml:span>,
                <xhtml:span class="hljs-string">"text"</xhtml:span>: <xhtml:span class="hljs-string">"This is a description of the link"</xhtml:span>,
                <xhtml:span class="hljs-string">"link_url"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/"</xhtml:span>
            },
        ]
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>If you were to use this methodology, you would alter the
<xhtml:code>options()</xhtml:code> method such that it does not return a
response object, but instead return a view model with the
documentation.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">My</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">FooController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">protected</xhtml:span> $viewModelMap = <xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-comment">/* ... */</xhtml:span>);

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">options</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span>
    </xhtml:span>{
        $response = <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;getResponse();
        $headers  = $response-&gt;getHeaders();

        <xhtml:span class="hljs-comment">// Get a view model based on Accept types</xhtml:span>
        $model    = <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;acceptableViewModelSelector(<xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;viewModelMap);

        <xhtml:span class="hljs-comment">// If you want to vary based on whether this is a collection or an</xhtml:span>
        <xhtml:span class="hljs-comment">// individual item in that collection, check if an identifier from</xhtml:span>
        <xhtml:span class="hljs-comment">// the route is present</xhtml:span>
        <xhtml:span class="hljs-keyword">if</xhtml:span> (<xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;params()-&gt;fromRoute(<xhtml:span class="hljs-string">'id'</xhtml:span>, <xhtml:span class="hljs-keyword">false</xhtml:span>)) {
            <xhtml:span class="hljs-comment">// Still set the Allow header</xhtml:span>
            $headers-&gt;addHeaderLine(<xhtml:span class="hljs-string">'Allow'</xhtml:span>, implode(
                <xhtml:span class="hljs-string">','</xhtml:span>, 
                <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;allowedResourceMethods
            ));

            <xhtml:span class="hljs-comment">// Set documentation specification as variables</xhtml:span>
            $model-&gt;setVariables(<xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;getResourceDocumentationSpec());
            <xhtml:span class="hljs-keyword">return</xhtml:span> $model;
        }

        <xhtml:span class="hljs-comment">// Allow only retrieval and creation on collections</xhtml:span>
        $headers-&gt;addHeaderLine(<xhtml:span class="hljs-string">'Allow'</xhtml:span>, implode(
            <xhtml:span class="hljs-string">','</xhtml:span>,
            <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;allowedCollectionMethods
        ));
        $model-&gt;setVariables(<xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;getCollectionDocumentationSpec());
        <xhtml:span class="hljs-keyword">return</xhtml:span> $model;
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>I purposely didn't provide the implementations of the
<xhtml:code>getResourceDocumentationSpec()</xhtml:code> and
<xhtml:code>getCollectionDocumentationSpec()</xhtml: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.</xhtml:p>
<xhtml:p><xhtml:strong>However, there's one cautionary tale to tell</xhtml:strong>,
something I already mentioned: <xhtml:code>OPTIONS</xhtml:code>, per the
specification, is <xhtml:em>non-cacheable</xhtml:em>. What this means is that
everytime somebody makes an <xhtml:code>OPTIONS</xhtml: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 <xhtml:a href="http://www.mnot.net/blog/2012/10/29/NO_OPTIONS">blog posts urging
you not to use OPTIONS for documentation</xhtml:a>.</xhtml:p>
<xhtml:p>Which brings us to the second solution for end-user
documentation: a static page referenced via a hypermedia link.</xhtml:p>
<xhtml:p>This solution is insanely easy: you simply provide a
<xhtml:code>Link</xhtml:code> header in your response, and provide a
<xhtml:code>describedby</xhtml:code> reference pointing to the documentation
page:</xhtml:p>
<xhtml:pre><xhtml:code class="language-http hljs http" data-lang="http"><xhtml:span class="hljs-attribute">Link</xhtml:span>: &lt;http://example.com/api/documentation.md&gt;; rel="describedby"
</xhtml:code></xhtml:pre>
<xhtml: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 <xhtml:code>Link</xhtml:code> header to your
response.</xhtml:p>
<xhtml:p>The latter, adding the link header, might look like this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">My</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">EventManager</xhtml:span>\<xhtml:span class="hljs-title">EventManagerInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">FooController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractRestfulController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">setEventManager</xhtml:span><xhtml:span class="hljs-params">(EventManagerInterface $events)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">parent</xhtml:span>::setEventManager($events);
        $events-&gt;attach(<xhtml:span class="hljs-string">'dispatch'</xhtml:span>, <xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-keyword">$this</xhtml:span>, <xhtml:span class="hljs-string">'injectLinkHeader'</xhtml:span>), <xhtml:span class="hljs-number">20</xhtml:span>);
    }

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">injectLinkHeader</xhtml:span><xhtml:span class="hljs-params">($e)</xhtml:span>
    </xhtml:span>{
        $response = $e-&gt;getResponse();
        $headers  = $response-&gt;getHeaders();
        $headers-&gt;addHeaderLine(<xhtml:span class="hljs-string">'Link'</xhtml:span>, sprintf(
            <xhtml:span class="hljs-string">'&lt;%s&gt;; rel="describedby"'</xhtml:span>, 
            <xhtml:span class="hljs-keyword">$this</xhtml:span>-&gt;url(<xhtml:span class="hljs-string">'documentation-route-name'</xhtml:span>)
        ));
    }
}
</xhtml:code></xhtml:pre>
<xhtml: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.</xhtml:p>
<xhtml: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: <xhtml:a href="https://github.com/weierophinney/PhlySimplePage">PhlySimplePage</xhtml:a>
and <xhtml:a href="https://github.com/Soflomo/Prototype">Soflomo\Prototype</xhtml:a>.
<xhtml:em>(Disclosure: I'm the author of PhlySimplePage.)</xhtml:em></xhtml:p>
<xhtml: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.
<xhtml:code>Soflomo\Prototype</xhtml:code> has slightly simpler configuration,
so I'll demonstrate it here:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">array</xhtml:span>(
    <xhtml:span class="hljs-string">'soflomo_prototype'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'documentation-route-name'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'route'</xhtml:span>    =&gt; <xhtml:span class="hljs-string">'/api/documentation'</xhtml:span>,
            <xhtml:span class="hljs-string">'template'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'api/documentation'</xhtml:span>,
        ),
    ),
    <xhtml:span class="hljs-string">'view_manager'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'template_map'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'api/documentation'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">__DIR__</xhtml:span> . <xhtml:span class="hljs-string">'/../view/api/documentation.phtml'</xhtml:span>,
        ),
    ),
);
</xhtml:code></xhtml:pre>
<xhtml:p>I personally have been using the <xhtml:code>Link</xhtml:code> header
solution, as it's so simple to implement. It does <xhtml:em>not</xhtml: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.</xhtml:p>
<xhtml:h2>Conclusions</xhtml:h2>
<xhtml: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:</xhtml:p>
<xhtml:ul>
<xhtml:li>What endpoint(s) is (are) available.</xhtml:li>
<xhtml:li>Which operations are available for each endpoint.
<xhtml:ul>
<xhtml:li>What payloads are expected by the endpoint.</xhtml:li>
<xhtml:li>What payloads can a user expect in return.</xhtml:li>
<xhtml:li>What media types may be used for requests.</xhtml:li>
<xhtml:li>What media types may be expected in responses.</xhtml:li>
</xhtml:ul>
</xhtml:li>
</xhtml:ul>
<xhtml:p>Additionally, make sure that you do the
<xhtml:code>OPTIONS</xhtml:code>/<xhtml:code>Allow</xhtml: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!</xhtml:p>
<xhtml:h2>Next time</xhtml:h2>
<xhtml: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?</xhtml:p>
<xhtml:p>In upcoming parts, I'll talk about ZF2's
<xhtml:code>AbstractRestfulController</xhtml: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.</xhtml:p>
<xhtml:h3>Updates</xhtml:h3>
<xhtml:p><xhtml:em>Note: I'll update this post with links to the other posts in
the series as I publish them.</xhtml:em></xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:a href="/blog/2013-02-11-restful-apis-with-zf2-part-1.html">Part
1</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="/blog/2013-02-13-restful-apis-with-zf2-part-2.html">Part
2</xhtml:a></xhtml:li>
</xhtml:ul>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2013-02-25-restful-apis-with-zf2-part-3.html">
RESTful APIs with ZF2, Part 3</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2013-02-25T06:29:00-06:00">25
February 2013</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[RESTful APIs with ZF2, Part 2]]></title>
    <published>2013-02-13T07:40:00-06:00</published>
    <updated>2013-02-13T07:40:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2013-02-13-restful-apis-with-zf2-part-2.html"/>
    <id>https://mwop.net/blog/2013-02-13-restful-apis-with-zf2-part-2.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>In my <xhtml:a href="/blog/2013-02-11-restful-apis-with-zf2-part-1.html">last post</xhtml: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.</xhtml:p>
<xhtml:p>In this post, I cover an aspect of RESTful APIs that's often
overlooked: reporting problems.</xhtml:p>
<xhtml:h2>Background</xhtml:h2>
<xhtml: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.</xhtml:p>
<xhtml:p>In consuming APIs, I've come to the following conclusions:</xhtml:p>
<xhtml:ul>
<xhtml: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.</xhtml:li>
<xhtml:li>Errors need to be reported consistently. Don't report the error
one way one time, and another way the next.</xhtml:li>
<xhtml:li><xhtml:strong>DO</xhtml:strong> use HTTP status codes to indicate an error
happened. Nothing is more irksome than getting back a 200 status
with an error payload.</xhtml:li>
<xhtml: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.</xhtml:li>
</xhtml:ul>
<xhtml:h2>Why Status Codes Aren't Enough</xhtml:h2>
<xhtml:p>Since REST leverages and builds on HTTP, an expedient solution
for reporting problems is to simply use <xhtml:a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html">HTTP
status codes</xhtml:a>. These are well understood by web developers,
right?</xhtml:p>
<xhtml:p><xhtml:code>4xx</xhtml: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.</xhtml:p>
<xhtml: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 <xhtml:code>5xx</xhtml:code>
series of status codes is sparse and wholly unsuited to reporting
errors of these types — <xhtml:em>though you'll likely still want to use
a <xhtml:code>500</xhtml:code> status to report the failure</xhtml: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?</xhtml:p>
<xhtml: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 <xhtml:em>details</xhtml: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.</xhtml:p>
<xhtml:h2>Custom Media Types</xhtml:h2>
<xhtml: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.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:p>In the world of JSON, I've come across two error media types
that appear to be gaining traction:
<xhtml:code>application/api-problem+json</xhtml:code> and
<xhtml:code>application/vnd.error+json</xhtml:code></xhtml:p>
<xhtml:h3>API-Problem</xhtml:h3>
<xhtml:p>This particular media type is <xhtml:a href="http://tools.ietf.org/html/draft-nottingham-http-problem-02">via
the IETF</xhtml:a>. Like HAL, it provides formats in both JSON and XML,
making it a nice cross-platform choice.</xhtml:p>
<xhtml:p>As noted already, the media type is
<xhtml:code>application/api-problem+json</xhtml:code>. The representation is a
single resource, with the following properties:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>describedBy</xhtml:strong>: a URL to a document describing
the error condition (required)</xhtml:li>
<xhtml:li><xhtml:strong>title</xhtml:strong>: a brief title for the error condition
(required)</xhtml:li>
<xhtml:li><xhtml:strong>httpStatus</xhtml:strong>: the HTTP status code for the
current request (optional)</xhtml:li>
<xhtml:li><xhtml:strong>detail</xhtml:strong>: error details specific to this request
(optional)</xhtml:li>
<xhtml:li><xhtml:strong>supportId</xhtml:strong>: a URL to the specific problem
occurrence (e.g., to a log message) (optional)</xhtml:li>
</xhtml:ul>
<xhtml:p>As an example:</xhtml:p>
<xhtml:pre><xhtml:code class="language-http hljs http" data-lang="http">HTTP/1.1 <xhtml:span class="hljs-number">500</xhtml:span> Internal Error
<xhtml:span class="hljs-attribute">Content-Type</xhtml:span>: application/api-problem+json

{
    "describedBy": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html",
    "detail": "Status failed validation",
    "httpStatus": 500,
    "title": "Internal Server Error"
}
</xhtml:code></xhtml:pre>
<xhtml: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.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:h3>vnd.error</xhtml:h3>
<xhtml:p>This is a <xhtml:a href="https://github.com/blongden/vnd.error">proposed media type</xhtml:a>
within the HAL community. Like HAL, it provides formats in both
JSON and XML, making it a nice cross-platform choice.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:p>The response payload is an array of objects. Each object has the
following members:</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>logRef</xhtml:strong>: a unique identifier for the specific
error which can then be used to identify the error within
server-side logs (required)</xhtml:li>
<xhtml:li><xhtml:strong>message</xhtml:strong>: the error message itself
(required)</xhtml:li>
<xhtml:li><xhtml:strong>_links</xhtml:strong>: HAL-compatible links. Typically,
"help", "describes", and/or "describedBy" relations will be defined
here.</xhtml:li>
</xhtml:ul>
<xhtml:p>As an example, let's consider the API-Problem example I had
earlier, and provide a <xhtml:code>vnd.error</xhtml:code> equivalent:</xhtml:p>
<xhtml:pre><xhtml:code class="language-http hljs http" data-lang="http">HTTP/1.1 <xhtml:span class="hljs-number">500</xhtml:span> Internal Error
<xhtml:span class="hljs-attribute">Content-Type</xhtml:span>: application/vnd.error+json

[
    {
        "logRef": "someSha1HashMostLikely",
        "message": "Status failed validation",
        "_links": {
            "describedBy": {"href": "http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html"}
        }
    }
]
</xhtml:code></xhtml:pre>
<xhtml:p><xhtml:code>vnd.error</xhtml:code> 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).</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:h2>Summary</xhtml:h2>
<xhtml: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.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:strong>DO</xhtml:strong> use appropriate HTTP status codes to
indicate an error happened.</xhtml:li>
<xhtml:li>Report errors in a format I have indicated I will Accept (as in
the HTTP header).</xhtml:li>
<xhtml: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 <xhtml:em>can</xhtml: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.</xhtml:li>
<xhtml: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.</xhtml:li>
</xhtml:ul>
<xhtml:p>Which brings me to…</xhtml:p>
<xhtml:h2>Next time</xhtml:h2>
<xhtml: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.</xhtml:p>
<xhtml:h3>Updates</xhtml:h3>
<xhtml:p><xhtml:em>Note: I'll update this post with links to the other posts in
the series as I publish them.</xhtml:em></xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:a href="/blog/2013-02-11-restful-apis-with-zf2-part-1.html">Part
1</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="/blog/2013-02-25-restful-apis-with-zf2-part-3.html">Part
3</xhtml:a></xhtml:li>
</xhtml:ul>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2013-02-13-restful-apis-with-zf2-part-2.html">
RESTful APIs with ZF2, Part 2</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2013-02-13T07:40:00-06:00">13
February 2013</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[RESTful APIs with ZF2, Part 1]]></title>
    <published>2013-02-12T05:42:00-06:00</published>
    <updated>2013-02-13T07:40:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2013-02-11-restful-apis-with-zf2-part-1.html"/>
    <id>https://mwop.net/blog/2013-02-11-restful-apis-with-zf2-part-1.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>RESTful APIs have been an interest of mine for a couple of
years, but due to <xhtml:a href="http://framework.zend.com/blog//zend-framework-2-0-0-stable-released.html">
circumstances</xhtml:a>, I've not had much chance to work with them in
any meaningful fashion until recently.</xhtml:p>
<xhtml:p><xhtml:a href="http://akrabat.com/">Rob Allen</xhtml:a> and I proposed a
workshop for <xhtml:a href="http://conference.phpbenelux.eu/2013/">PHP
Benelux 2013</xhtml: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.</xhtml:p>
<xhtml:h2>Background</xhtml:h2>
<xhtml: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:</xhtml:p>
<xhtml:ol>
<xhtml:li>JSON is fast becoming the preferred exchange format due to the
ease with which it de/serializes in almost every language.</xhtml:li>
<xhtml:li>The "holy grail" is <xhtml:a href="http://martinfowler.com/articles/richardsonMaturityModel.html">Richardson
Maturity Model</xhtml:a> Level 3.</xhtml:li>
<xhtml:li>It's really hard to achieve RMM level 3 with JSON.</xhtml:li>
</xhtml:ol>
<xhtml:h3>Richardson Maturity Model</xhtml:h3>
<xhtml:p>As a quick review, the Richardson Maturity Model has the
following 4 levels:</xhtml:p>
<xhtml:ul>
<xhtml: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.</xhtml:li>
<xhtml: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.,
<xhtml:code>/books</xhtml:code> as well as <xhtml:code>/books/life-of-pi</xhtml:code>). 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.</xhtml:li>
<xhtml: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.</xhtml:li>
<xhtml:li>Level 3: "Hypermedia Controls." Building on the previous level,
our resource representations now also include <xhtml:em>links</xhtml:em>, which
indicate what we can <xhtml:em>do next</xhtml: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.</xhtml:li>
</xhtml:ul>
<xhtml: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.)</xhtml:p>
<xhtml: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 <xhtml:a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</xhtml: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.</xhtml:p>
<xhtml:p><xhtml: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.</xhtml:em></xhtml:p>
<xhtml:p>Level 3, though, is where it becomes really interesting. The
idea that I can examine the represention <xhtml:em>alone</xhtml:em> in order to
understand what I can do next is very intriguing and
empowering.</xhtml:p>
<xhtml:h3>JSON and Hypermedia</xhtml:h3>
<xhtml:p>With XML, hypermedia basically comes for free. Add some
<xhtml:code>&lt;link&gt;</xhtml:code> elements to your representation, and
you're done — and don't forget the link <xhtml:code>rel</xhtml:code>ations!</xhtml:p>
<xhtml:p>JSON, however, is another story.</xhtml:p>
<xhtml:p>Where do the links go? <xhtml:em>There is no single, defined way to
represent a hyperlink in JSON.</xhtml:em></xhtml:p>
<xhtml:p>Fortunately, there are some emerging standards.</xhtml:p>
<xhtml:p>First is use of the <xhtml:a href="http://www.w3.org/wiki/LinkHeader">"Link" HTTP header</xhtml: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.</xhtml:p>
<xhtml:p><xhtml:a href="http://amundsen.com/media-types/collection/format/">Collection+JSON</xhtml: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.</xhtml:p>
<xhtml:p>What's captured my attention of late, however, is <xhtml:a href="http://stateless.co/hal_specification.html">Hypertext Application
Language</xhtml: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!</xhtml:p>
<xhtml:h3>HAL Media Types</xhtml:h3>
<xhtml:p>HAL defines two generic media types:
<xhtml:code>application/hal+xml</xhtml:code> and
<xhtml:code>application/hal+json</xhtml:code>. You will use these as the
response <xhtml:code>Content-Type</xhtml:code>, as they describe the response
representation; the client can simply request
<xhtml:code>application/json</xhtml:code>, and the response format remains
compatible.</xhtml:p>
<xhtml:h3>HAL and Links</xhtml:h3>
<xhtml: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 <xhtml:code>_links</xhtml:code> object:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
    }
}
</xhtml:code></xhtml:pre>
<xhtml: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.</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
        <xhtml:span class="hljs-string">"self"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status/1234"</xhtml:span>}
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>If a given relation can have multiple links, you provide instead
an array of objects:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
        <xhtml:span class="hljs-string">"self"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status/1234"</xhtml:span>},
        <xhtml:span class="hljs-string">"conversation"</xhtml:span>: [
            {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status/1237"</xhtml:span>},
            {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status/1241"</xhtml:span>}
        ]
    }
}
</xhtml:code></xhtml:pre>
<xhtml: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.</xhtml:p>
<xhtml:h3>HAL and Resources</xhtml:h3>
<xhtml: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
<xhtml:em>returned</xhtml:em> by the service.</xhtml:p>
<xhtml:p>So, as an example, you would POST the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-http hljs http" data-lang="http"><xhtml:span class="hljs-attribute">POST /api/status
Host</xhtml:span>: example.com
<xhtml:span class="hljs-attribute">Accept</xhtml:span>: application/json
<xhtml:span class="hljs-attribute">Content-Type</xhtml:span>: application/json

{
    "status": "This is my awesome status update!",
    "user": "mwop"
}
</xhtml:code></xhtml:pre>
<xhtml:p>And from that request, you'd receive the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-http hljs http" data-lang="http"><xhtml:span class="hljs-attribute">201 Created
Location</xhtml:span>: http://example.com/api/status/1347
<xhtml:span class="hljs-attribute">Content-Type</xhtml:span>: 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"
}
</xhtml:code></xhtml:pre>
<xhtml:h3>HAL and Embedded Resources</xhtml:h3>
<xhtml:p>The other important thing that HAL defines is how to
<xhtml:em>embed</xhtml: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.</xhtml:p>
<xhtml:p>Embedded resources are represented inside an
<xhtml:code>_embedded</xhtml:code> object of the representation, and, as
resources, contain their own <xhtml:code>_links</xhtml:code> 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
<xhtml:em>collections</xhtml:em> in HAL.</xhtml:p>
<xhtml: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.</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
        <xhtml:span class="hljs-string">"self"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status/1347"</xhtml:span>}
    },
    <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"1347"</xhtml:span>,
    <xhtml:span class="hljs-string">"timestamp"</xhtml:span>: <xhtml:span class="hljs-string">"2013-02-11 23:33:47"</xhtml:span>,
    <xhtml:span class="hljs-string">"status"</xhtml:span>: <xhtml:span class="hljs-string">"This is my awesome status update!"</xhtml:span>,
    <xhtml:span class="hljs-string">"_embedded"</xhtml:span>: {
        <xhtml:span class="hljs-string">"user"</xhtml:span>: {
            <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
                <xhtml:span class="hljs-string">"self"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/user/mwop"</xhtml:span>}
            }
            <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"mwop"</xhtml:span>,
            <xhtml:span class="hljs-string">"name"</xhtml:span>: <xhtml:span class="hljs-string">"Matthew Weier O'Phinney"</xhtml:span>,
            <xhtml:span class="hljs-string">"url"</xhtml:span>: <xhtml:span class="hljs-string">"http://mwop.net"</xhtml:span>
        }
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>I've moved the "user" out of the representation, and into the
<xhtml:code>_embedded</xhtml:code> object — because this is where you define
embedded resources. Note that the "user" is a standard HAL resource
itself — containing hypermedia links.</xhtml:p>
<xhtml:p>Now let's look at a collection:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
        <xhtml:span class="hljs-string">"self"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status"</xhtml:span>},
        <xhtml:span class="hljs-string">"next"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status?page=2"</xhtml:span>},
        <xhtml:span class="hljs-string">"last"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status?page=100"</xhtml:span>}
    },
    <xhtml:span class="hljs-string">"count"</xhtml:span>: <xhtml:span class="hljs-number">2973</xhtml:span>,
    <xhtml:span class="hljs-string">"per_page"</xhtml:span>: <xhtml:span class="hljs-number">30</xhtml:span>,
    <xhtml:span class="hljs-string">"page"</xhtml:span>: <xhtml:span class="hljs-number">1</xhtml:span>,
    <xhtml:span class="hljs-string">"_embedded"</xhtml:span>: {
        <xhtml:span class="hljs-string">"status"</xhtml:span>: [
            {
                <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
                    <xhtml:span class="hljs-string">"self"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/status/1347"</xhtml:span>}
                },
                <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"1347"</xhtml:span>,
                <xhtml:span class="hljs-string">"timestamp"</xhtml:span>: <xhtml:span class="hljs-string">"2013-02-11 23:33:47"</xhtml:span>,
                <xhtml:span class="hljs-string">"status"</xhtml:span>: <xhtml:span class="hljs-string">"This is my awesome status update!"</xhtml:span>,
                <xhtml:span class="hljs-string">"_embedded"</xhtml:span>: {
                    <xhtml:span class="hljs-string">"user"</xhtml:span>: {
                        <xhtml:span class="hljs-string">"_links"</xhtml:span>: {
                            <xhtml:span class="hljs-string">"self"</xhtml:span>: {<xhtml:span class="hljs-string">"href"</xhtml:span>: <xhtml:span class="hljs-string">"http://example.com/api/user/mwop"</xhtml:span>}
                        }
                        <xhtml:span class="hljs-string">"id"</xhtml:span>: <xhtml:span class="hljs-string">"mwop"</xhtml:span>,
                        <xhtml:span class="hljs-string">"name"</xhtml:span>: <xhtml:span class="hljs-string">"Matthew Weier O'Phinney"</xhtml:span>,
                        <xhtml:span class="hljs-string">"url"</xhtml:span>: <xhtml:span class="hljs-string">"http://mwop.net"</xhtml:span>
                    }
                }
            }
            <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
        ]
    }
}
</xhtml:code></xhtml:pre>
<xhtml: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.</xhtml:p>
<xhtml:p>Also note that you can nest resources — simply include an
<xhtml:code>_embedded</xhtml:code> 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.</xhtml:p>
<xhtml:h2>Next Time</xhtml:h2>
<xhtml: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.</xhtml:p>
<xhtml:p>I'll get there. But there's another detour to take: reporting
errors.</xhtml:p>
<xhtml:h3>Updates</xhtml:h3>
<xhtml:p><xhtml:em>Note: I'll update this post with links to the other posts in
the series as I publish them.</xhtml:em></xhtml:p>
<xhtml:ul>
<xhtml:li><xhtml:a href="/blog/2013-02-13-restful-apis-with-zf2-part-2.html">Part
2</xhtml:a></xhtml:li>
<xhtml:li><xhtml:a href="/blog/2013-02-25-restful-apis-with-zf2-part-3.html">Part
3</xhtml:a></xhtml:li>
</xhtml:ul>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2013-02-11-restful-apis-with-zf2-part-1.html">
RESTful APIs with ZF2, Part 1</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2013-02-12T05:42:00-06:00">12
February 2013</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[Zend Server, ZF2, and Page Caching]]></title>
    <published>2012-11-05T15:25:00-06:00</published>
    <updated>2012-11-05T15:25:00-06:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2012-11-05-zend-server-caching.html"/>
    <id>https://mwop.net/blog/2012-11-05-zend-server-caching.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>Zend Server has a very cool <xhtml:a href="https://www.youtube.com/watch_v=i2XXn2SA5zM.html">Page Caching
feature</xhtml:a>. Basically, you can provide URLs or URL regular
expressions, and tell Zend Server to provide full-page caching of
those pages. This can provide a tremendous performance boost,
without needing to change anything in your application structure;
simply enable it for a set of pages, and sit back and relax.</xhtml:p>
<xhtml:p><xhtml:img src="/images/blog/2012-11-04-Server-CachingRule.png" alt="Zend Server Page Caching" title="Zend Server Page Caching"/></xhtml:p>
<xhtml:p>However, this feature is not entirely straight-forward when
using a framework that provides its own routing, such as ZF2. The
reason is because it assumes by default that each match maps to a
specific file on the filesystem, and prepares the caching based on
the actual <xhtml:em>file</xhtml:em> it hits. What this means for ZF2 and other
similar frameworks is that any page that matches will return the
cached version for the <xhtml:em>first</xhtml:em> match that also matches the
same <xhtml:em>file</xhtml:em> — i.e., <xhtml:code>index.php</xhtml:code> in ZF2. That's
every page the framework handles. As an example, if I match on
<xhtml:code>/article/\d+</xhtml:code>, it matches this to the file
<xhtml:code>index.php</xhtml:code>, and then any other match that resolves to
<xhtml:code>index.php</xhtml:code> gets served that same page. Not handy.</xhtml:p>
<xhtml:p>The good part is that there's a way around this.</xhtml:p>
<xhtml:p>When creating or modifying a caching rule, simply look for the
text, "Create a separate cached page for each value of:" and click
the "Add Parameter" button. Select <xhtml:code>_SERVER</xhtml:code> from the
dropdown, and type <xhtml:code>[REQUEST_URI]</xhtml:code> for the value. Once
saved, each page that matches the pattern will be cached
separately.</xhtml:p>
<xhtml:p><xhtml:img src="/images/blog/2012-11-04-Server-Caching-Request.png" alt="Zend Server Page Caching by Request" title="Zend Server Page Caching by Request"/></xhtml:p>
<xhtml:p>Note: the <xhtml:code>_SERVER</xhtml:code> key may vary based on what
environment/OS you're deployed in. Additionally, it may differ
based on how you define rewrite rules — some frameworks and CMS
systems will append to the query string, for instance, in which
case you may want to select the "entire query string" parameter
instead of <xhtml:code>_SERVER</xhtml:code>; the point is, there's likely a way
for you to configure it.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2012-11-05-zend-server-caching.html">Zend
Server, ZF2, and Page Caching</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2012-11-05T15:25:00-06:00">5
November 2012</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[OpenShift, ZF2, and Composer]]></title>
    <published>2012-11-01T15:25:00-05:00</published>
    <updated>2012-11-01T15:25:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2012-11-01-openshift-zf2-composer.html"/>
    <id>https://mwop.net/blog/2012-11-01-openshift-zf2-composer.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>I was recently shopping around for inexpensive cloud hosting; I
want to try out a couple of ideas that may or may not have much
traffic, but which aren't suited for my VPS setup (the excellent
<xhtml:a href="http://servergrove.com/">ServerGrove</xhtml:a>); additionally,
I'm unsure how long I will maintain these projects. My budget for
this is quite small as a result; I'm already paying for hosting,
and am quite happy with it, so this is really for experimental
stuff.</xhtml:p>
<xhtml:p>I considered Amazon, Orchestra.io, and a few others, but was
concerned about the idea of a ~$50/month cost for something I'm
uncertain about.</xhtml:p>
<xhtml:p>When I asked in <xhtml:a href="irc://irc.freenode.net/zftalk.dev">#zftalk.dev</xhtml:a>, someone
suggested <xhtml:a href="http://openshift.redhat.com/">OpenShift</xhtml:a> as
an idea, and coincidentally, the very next day <xhtml:a href="http://www.zend.com/en/company/news/press/379_red-hat-expands-openshift-ecosystem-with-zend-partnership-to-offer-professional-grade-environment-for-php-developers">
Zend announced a partnership with RedHat surrounding OpenShift</xhtml:a>.
The stars were in alignment.</xhtml:p>
<xhtml:p>In the past month, in the few spare moments I've had (which
included an excellent OpenShift hackathon at ZendCon), I've created
a quick application that I've deployed and tested in OpenShift.
These are my findings.</xhtml:p>
<xhtml:h2>ZF2</xhtml:h2>
<xhtml:p>I didn't really have to do anything different to have <xhtml:a href="http://framework.zend.com/">zf2</xhtml:a> work; the standard
<xhtml:code>.htaccess</xhtml:code> provided in the skeleton application worked
flawlessly the first time (I've worked with some cloud environments
where this is not the case).</xhtml:p>
<xhtml:p>The only frustration I had was the default directory structure
OpenShift foists upon us:</xhtml:p>
<xhtml:pre><xhtml:code class="language-powershell hljs powershell" data-lang="powershell"><xhtml:span class="hljs-keyword">data</xhtml:span>/
libs/
misc/
php/
</xhtml:code></xhtml:pre>
<xhtml:p>This is not terrible, by any stretch. However, it's attempting
to dictate the application structure, which I'm not terribly happy
with — particularly as my structure may vary based on the framework
I'm using (or not!), and because I may already have a project
written that I simply want to deploy.</xhtml:p>
<xhtml:p>In particular, the <xhtml:code>php</xhtml:code> directory is galling — it's
simply the document root. Most frameworks I've used or seen call
the equivalent directory <xhtml:code>public</xhtml:code>, or <xhtml:code>web</xhtml:code>,
or <xhtml:code>html</xhtml:code> — but never <xhtml:code>php</xhtml:code> (in large part
because the only PHP file under the document root in most
frameworks is the <xhtml:code>index.php</xhtml:code> that acts as the front
controller). It would be nice if this were configurable.</xhtml:p>
<xhtml:p>This conflicts a bit with how a ZF2 app is structured. I ended
up doing the following:</xhtml:p>
<xhtml:ul>
<xhtml:li>Removed <xhtml:code>php</xhtml:code> and symlinked my <xhtml:code>public</xhtml:code>
directory to it.</xhtml:li>
<xhtml:li>Removed <xhtml:code>libs</xhtml:code> and symlinked my <xhtml:code>vendor</xhtml:code>
directory to it.</xhtml:li>
<xhtml:li>Removed <xhtml:code>misc</xhtml:code> as I had no need to it.</xhtml:li>
</xhtml:ul>
<xhtml:p>Nothing too big, thankfully — but problematic from the
perspective of, "I've already developed this app, but now I have to
make changes for it to work on a specific cloud vendor."</xhtml:p>
<xhtml:h2>Composer</xhtml:h2>
<xhtml:p>My next question was how to use <xhtml:a href="http://getcomposer.org/">Composer</xhtml:a> during my deployment
process, and some some googling <xhtml:a href="https://openshift.redhat.com/community/content/support-for-git-clone-on-the-server-aka-support-php-composerphar">
found some answers for me</xhtml:a>.</xhtml:p>
<xhtml:p>Basically, I needed to create a <xhtml:code>deploy</xhtml:code> task that
does two things:</xhtml:p>
<xhtml:ul>
<xhtml:li>Unset the <xhtml:code>GIT_DIR</xhtml:code> environment variable. Evidently,
the build process operates as part of a git hook, and since
Composer often uses git repositories, this can lead to
problems.</xhtml:li>
<xhtml:li>Change directory to <xhtml:code>OPENSHIFT_REPO_DIR</xhtml:code>, which is
where the application root (not document root!) lives.</xhtml:li>
</xhtml:ul>
<xhtml:p>Once I did those, I could run my normal composer installation.
The <xhtml:code>deploy</xhtml:code> task looks like this:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash"><xhtml:span class="hljs-meta">#!/bin/bash</xhtml:span>
<xhtml:span class="hljs-comment"># .openshift/action_hooks/deploy</xhtml:span>
( <xhtml:span class="hljs-built_in">unset</xhtml:span> GIT_DIR ; <xhtml:span class="hljs-built_in">cd</xhtml:span> <xhtml:span class="hljs-variable">$OPENSHIFT_REPO_DIR</xhtml:span> ; /usr/<xhtml:span class="hljs-built_in">local</xhtml:span>/zend/bin/php composer.phar install )
</xhtml:code></xhtml:pre>
<xhtml:p>This leads into my next topic.</xhtml:p>
<xhtml:h2>Deployment</xhtml:h2>
<xhtml:p>First off, as you probably guessed from that last secton, there
<xhtml:strong>are</xhtml:strong> hooks for deployment — it doesn't have to be
simply git. I like this, as I may have additional things I want to
do during deployment, such as retrieving and installing
site-specific configuration files, installing Composer-defined
dependencies (as already noted), etc.</xhtml:p>
<xhtml:p>Over all, this is pretty seamless, but it's not without issues.
I've been told that some of my issues are being worked on, so those
I won't bring up here. The ones that were a bit strange, and which
caught me by surprise, though, were:</xhtml:p>
<xhtml:ul>
<xhtml:li>Though the build process creates the site build from git, your
<xhtml:strong>submodules are not updated recursively</xhtml:strong>. This
tripped me up, as I was using <xhtml:a href="https://github.com/EvanDotPro/EdpMarkdown">EdpMarkdown</xhtml:a>, and
had installed it as a submodule. I ended up having to import it,
and its own submodule, directly into my project so that it would
work.</xhtml:li>
<xhtml:li>I installed the <xhtml:a href="http://www.mongodb.org/">MongoDB</xhtml:a>
cartridge. Ironically, it was not then enabled in Zend Server, and
I had to go do this. This should be turnkey.</xhtml:li>
<xhtml:li><xhtml:code>/usr/bin/php</xhtml:code> is not the same as
<xhtml:code>/usr/local/zend/bin/php</xhtml:code>. This makes no sense to me if
I've installed Zend Server as my base gear. Considering they're
different versions, this can be hugely misleading and lead to
errors. I understand there are reasons to have both — so simply be
aware that if you use the Zend Server gear, your tasks likely
should use <xhtml:code>/usr/local/zend/bin/php</xhtml:code>.</xhtml:li>
</xhtml:ul>
<xhtml:h2>The good parts?</xhtml:h2>
<xhtml:ul>
<xhtml:li><xhtml:a href="https://openshift.redhat.com/community/faq/i-have-deployed-my-app-but-i-don%E2%80%99t-like-telling-people-to-visit-myapp-myusernamerhcloudcom-how-c">
You can alias an application to a DNS CNAME</xhtml:a> — meaning you can
point your domain name to your OpenShift applications.
Awesome!</xhtml:li>
<xhtml:li>Simplicity of adding capabilities, such as Mongo, MySQL, Cron,
and others. In most cases, this is simply a "click on the button"
and it's installed and available.</xhtml:li>
<xhtml:li><xhtml:a href="http://www.zend.com/en/products/server">Zend
Server</xhtml:a>. For most PHP extensions, I can turn them on or off with
a few mouse clicks. If I want page-level caching, I don't have to
do anything to my application; I can simply setup some rules in the
Zend Server interface and get on with it, and enjoy tremendous
boosts to performance. I used to enjoy taming and tuning servers;
most days anymore, I just want them to work.</xhtml:li>
<xhtml:li><xhtml:a href="https://openshift.redhat.com/community/developers/remote-access">SSH</xhtml:a>
access to the server, with a number of commands to which I've been
given <xhtml:code>sudoer</xhtml:code> access. If you're going to sandbox
somebody, this is a fantastic way to do it. Oh, also: SSH tunnels
to services like Mongo and MySQL just work (via the
<xhtml:code>rhc-port-forward</xhtml:code> command).</xhtml:li>
</xhtml:ul>
<xhtml:h2>Summary</xhtml:h2>
<xhtml:p>Over all, I'm quite pleased. While it took me a bit to find the
various incantations I needed, the service is quite flexible. For
my needs, considering I'm doing experimental stuff, the price can't
be beat (the current developer preview is free). Considering most
stuff I do will fall into this or the basic tier, and that most
cartridges do not end up counting against your alotment of gears,
the pricing ($0.05/hour) is extremely competitive.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2012-11-01-openshift-zf2-composer.html">OpenShift,
ZF2, and Composer</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2012-11-01T15:25:00-05:00">1 November
2012</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[ZF2 Modules Quickstart (Screencast)]]></title>
    <published>2012-09-19T13:10:00-05:00</published>
    <updated>2012-09-19T13:10:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2012-09-19-zf2-module-screencast.html"/>
    <id>https://mwop.net/blog/2012-09-19-zf2-module-screencast.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>One of the exciting features of the newly released Zend
Framework 2 is the new module system.</xhtml:p>
<xhtml:p>While ZF1 had modules, they were difficult to manage. All
resources for all modules were initialized on each request, and
bootstrapping modules was an onerous task. Due to the difficulties,
modules were never truly "plug-and-play", and thus no ecosystem
ever evolved for sharing modules.</xhtml:p>
<xhtml:p>In Zend Framework 2, we've architected the MVC from the ground
up to make modular applications as easy as possible. Within ZF2,
the MVC simply cares about events and services — and controllers
are simply one kind of service. As such, modules are primarily
about telling the MVC about services and wiring event
listeners.</xhtml:p>
<xhtml:p>To give you an example, in this tutorial, I'll show you how to
install the Zend Framework 2 skeleton application, and we'll then
install a module and see how easy it is to add it to the
application and then configure it.</xhtml:p>
<xhtml:p>To keep things simple, I'm using a unix-like environment. As
such, if you are on Windows, you may not have the same command-line
tools available. If you are in such a situation, perhaps try this
inside a Linux virtual machine.</xhtml:p>
<xhtml:p><xhtml:a href="https://vimeo.com/49775540">Zend Framework 2 Module
Quickstart</xhtml:a></xhtml:p>
<xhtml:p>Let's start by creating a new project. We'll execute a few
commands to download a skeleton application archive and extract
it.</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ mkdir newproject
$ <xhtml:span class="hljs-built_in">cd</xhtml:span> newproject
$ wget https://github.com/zendframework/ZendSkeletonApplication/tarball/master \
&gt; -O ZendSkeletonApplication.tgz
$ tar xzf ZendSkeletonApplication.tgz --strip-components=1
</xhtml:code></xhtml:pre>
<xhtml:p>The Zend Framework skeleton application can be downloaded
directly off of <xhtml:a href="https://github.com">GitHub</xhtml:a>. I'm
showing using the download from master, but you can also download a
tarball or zipball for individual tags as well. Because the
download URL does not include an extension, I use the
<xhtml:code>-O</xhtml:code> switch to tell <xhtml:code>wget</xhtml:code> what filename to
save to.</xhtml:p>
<xhtml:p><xhtml:code>tar</xhtml:code> has a nice option,
<xhtml:code>--strip-components</xhtml:code>, which allows you to tell it to
descend a certain number of levels deep into the archive when
deflating. Since I know the tarball has a top-level directory named
after the repository and a sha1, I'm simply telling
<xhtml:code>tar</xhtml:code> to skip that and give me the contents of its child
directory.</xhtml:p>
<xhtml:p>At this point you have the skeleton application, but it has no
dependencies — not even Zend Framework itself! Let's rectify that
situation. We'll use the dependency management tool <xhtml:a href="https://getcomposer.org/">Composer</xhtml:a> to do this. We include the
Composer phar file within the skeleton application to make this
fairly easy. Simply execute the following:</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ php composer.phar install
</xhtml:code></xhtml:pre>
<xhtml:p>You may get a notice indicating that the composer version is
older, and to run <xhtml:code>self-update</xhtml:code>; you can ignore that for
now.</xhtml:p>
<xhtml:p>If all goes well, you should now have Zend Framework installed.
Let's test it out. I'm going to use the built-in web server in PHP
5.4 to demonstrate.</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ <xhtml:span class="hljs-built_in">cd</xhtml:span> public
$ php -S localhost:8080
</xhtml:code></xhtml:pre>
<xhtml:p>If I browse to <xhtml:code>http://localhost:8080</xhtml:code> I should now
see the landing page for the skeleton application.</xhtml:p>
<xhtml:p><xhtml:img src="/images/screencasts/2012-09-19-zf2-module-screencast-01-zsa.png" alt=""/></xhtml:p>
<xhtml:p>Let's add a module to the application. Many sites require a
contact form. I've written one as a module some time ago, and
called it <xhtml:a href="https://github.com/weierophinney/PhlyContact">PhlyContact</xhtml:a>. To
install it, I'll edit my project's <xhtml:code>composer.json</xhtml:code> and
tell it about that dependency:</xhtml:p>
<xhtml:pre><xhtml:code class="language-javascript hljs javascript" data-lang="javascript">{
    <xhtml:span class="hljs-string">"require"</xhtml:span>: {
        <xhtml:span class="hljs-string">"php"</xhtml:span>: <xhtml:span class="hljs-string">"&gt;=5.3.3"</xhtml:span>,
        <xhtml:span class="hljs-string">"zendframework/zendframework"</xhtml:span>: <xhtml:span class="hljs-string">"dev-master"</xhtml:span>,
        <xhtml:span class="hljs-string">"phly/phly-contact"</xhtml:span>: <xhtml:span class="hljs-string">"dev-master"</xhtml:span>
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>I know the name of the component from <xhtml:a href="http://packagist.org/">http://packagist.org/</xhtml:a>, and I'm telling
Composer that I want to use whatever the latest version is on its
master branch on GitHub. I happen to also know that PhlyContact
requires a dev-master version of Zend Framework, so I'll alter that
dependency for now.</xhtml:p>
<xhtml:p>Now, we need to tell composer to update our dependencies.</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ php composer.phar update
</xhtml:code></xhtml:pre>
<xhtml:p>After executing the command, we should now see that it has
installed; this may take a little while.</xhtml:p>
<xhtml:p>You need to inform the application about the module. This is so
that we don't have to perform expensive file-system scanning
operations, but also to make it explicit in your code what modules
you're actually using. Enabling a module is usually as easy as
adding an entry to <xhtml:code>config/application.config.php</xhtml:code>:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-string">'modules'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
    <xhtml:span class="hljs-string">'Application'</xhtml:span>,
    <xhtml:span class="hljs-string">'PhlyContact'</xhtml:span>,
),
</xhtml:code></xhtml:pre>
<xhtml:p>This particular module provides some reasonable defaults. In
particular, it uses a CAPTCHA adapter that doesn't require
additional configuration, and assumes that you will want to use the
default <xhtml:code>Sendmail</xhtml:code> mail transport. As such, we can
simply browse to it now. I happen to know that the module defines a
<xhtml:code>/contact</xhtml:code> end point. Let's fire up our PHP web server
again, and browse to that URL.</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ <xhtml:span class="hljs-built_in">cd</xhtml:span> public
$ php -S localhost:8080
</xhtml:code></xhtml:pre>
<xhtml:p><xhtml:img src="/images/screencasts/2012-09-19-zf2-module-screencast-02-contact.png" alt=""/></xhtml:p>
<xhtml:p>It just works!</xhtml:p>
<xhtml:p>One philosophy we have for distributable modules in Zend
Framework 2 is that you should not need to touch the code in
modules you install in your application. Instead, you should be
able to configure and override behavior within the application
configuration or in your application's site-specific modules. Let's
alter the contact module to:</xhtml:p>
<xhtml:ul>
<xhtml:li>first, change the URL it responds to, and</xhtml:li>
<xhtml:li>second, use the "file" mail transport.</xhtml:li>
</xhtml:ul>
<xhtml:p>Let's look at the default configuration. I'll browse to
<xhtml:code>vendor/phly/phly-contact/config/</xhtml:code> and look at the
<xhtml:code>module.config.php</xhtml:code> file.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">array</xhtml:span>(
    <xhtml:span class="hljs-string">'phly_contact'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'captcha'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'class'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'dumb'</xhtml:span>,
        ),
        <xhtml:span class="hljs-string">'form'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'name'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'contact'</xhtml:span>,
        ),
        <xhtml:span class="hljs-string">'mail_transport'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'class'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'Zend\Mail\Transport\Sendmail'</xhtml:span>,
            <xhtml:span class="hljs-string">'options'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            )
        ),
        <xhtml:span class="hljs-string">'message'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-comment">/*
            'to' =&gt; array(
                'EMAIL HERE' =&gt; 'NAME HERE',
            ),
            'sender' =&gt; array(
                'address' =&gt; 'EMAIL HERE',
                'name'    =&gt; 'NAME HERE',
            ),
            'from' =&gt; array(
                'EMAIL HERE' =&gt; 'NAME HERE',
            ),
             */</xhtml:span>
        ),
    ),

    <xhtml:span class="hljs-comment">/* ... */</xhtml:span>

    <xhtml:span class="hljs-string">'router'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'routes'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'contact'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                <xhtml:span class="hljs-string">'type'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'Literal'</xhtml:span>,
                <xhtml:span class="hljs-string">'options'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                    <xhtml:span class="hljs-string">'route'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'/contact'</xhtml:span>,
                    <xhtml:span class="hljs-string">'defaults'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                        <xhtml:span class="hljs-string">'__NAMESPACE__'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'PhlyContact\Controller'</xhtml:span>,
                        <xhtml:span class="hljs-string">'controller'</xhtml:span>    =&gt; <xhtml:span class="hljs-string">'Contact'</xhtml:span>,
                        <xhtml:span class="hljs-string">'action'</xhtml:span>        =&gt; <xhtml:span class="hljs-string">'index'</xhtml:span>,
                    ),
                ),
                <xhtml:span class="hljs-string">'may_terminate'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">true</xhtml:span>,
                <xhtml:span class="hljs-string">'child_routes'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                    <xhtml:span class="hljs-string">'process'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                        <xhtml:span class="hljs-string">'type'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'Literal'</xhtml:span>,
                        <xhtml:span class="hljs-string">'options'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                            <xhtml:span class="hljs-string">'route'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'/process'</xhtml:span>,
                            <xhtml:span class="hljs-string">'defaults'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                                <xhtml:span class="hljs-string">'action'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'process'</xhtml:span>,
                            ),
                        ),
                    ),
                    <xhtml:span class="hljs-string">'thank-you'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                        <xhtml:span class="hljs-string">'type'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'Literal'</xhtml:span>,
                        <xhtml:span class="hljs-string">'options'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                            <xhtml:span class="hljs-string">'route'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'/thank-you'</xhtml:span>,
                            <xhtml:span class="hljs-string">'defaults'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                                <xhtml:span class="hljs-string">'action'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'thank-you'</xhtml:span>,
                            ),
                        ),
                    ),
                ),
            ),
        ),
    ),
    <xhtml:span class="hljs-comment">/* ... */</xhtml:span>
);
</xhtml:code></xhtml:pre>
<xhtml:p>Okay, that's interesting. I can define the captcha and options
to use, the name of the contact form, the mail transport I want to
use, and even who the email is sent from and who it goes to. In
addition, it defines some routes.</xhtml:p>
<xhtml:p>I'll create a new file,
<xhtml:code>config/autoload/phly-contact.local.php</xhtml:code>. This is a
local configuration file that will not be checked into my version
control system. Now, let's add some configuration. First, I'll
configure my mail transport.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">array</xhtml:span>(
    <xhtml:span class="hljs-string">'phly_contact'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'mail_transport'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'class'</xhtml:span>   =&gt; <xhtml:span class="hljs-string">'Zend\Mail\Transport\File'</xhtml:span>,
            <xhtml:span class="hljs-string">'options'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                <xhtml:span class="hljs-string">'path'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'data/mail/'</xhtml:span>,
            ),
        ),
    ),
);
</xhtml:code></xhtml:pre>
<xhtml:p>I'm telling the module to use the <xhtml:code>File</xhtml:code> mail
transport, and telling the transport where I want messages written.
By default, Zend Framework calls <xhtml:code>chdir()</xhtml:code> to change
directory to the project root, so I can reference a directory
relative to that. I'm simply going to write to a
<xhtml:code>data/mail/</xhtml:code> directory. Let's create that, and make it
world-writable for now to ensure the web server can write to it.
(In production, you'd only want it writable by the web server
user.)</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ mkdir -p data/mail
$ chmod a+rwX data/mail
</xhtml:code></xhtml:pre>
<xhtml:p>Now, let's change the base URL the contact form responds to; I
want it to respond to <xhtml:code>/contact-us</xhtml:code>. Another principle
of re-usable modules in ZF2 is that we recommend creating tree
routes for each module, with the root of the tree being a literal
route. This makes it easy to alter the base for routing, without
needing to redefine all the routes in the module.</xhtml:p>
<xhtml:p>I'll add the following to my local configuration, then. I'll
simply override the parent route for my module, named "contact",
and point it at a different URL.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">    <xhtml:span class="hljs-string">'router'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
        <xhtml:span class="hljs-string">'routes'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'contact'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                <xhtml:span class="hljs-string">'options'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
                    <xhtml:span class="hljs-string">'route'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'/contact-us'</xhtml:span>,
                ),
            ),
        ),
    ),
</xhtml:code></xhtml:pre>
<xhtml:p>Let's see if all this worked! Once again, I'll fire up PHP's
built-in web server.</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ <xhtml:span class="hljs-built_in">cd</xhtml:span> public
$ php -S localhost:8080
</xhtml:code></xhtml:pre>
<xhtml:p>Now, let's browse to
<xhtml:code>http://localhost:8080/contact-us</xhtml:code> — looks good! Just as
an experiment, let's try the previously configured URL,
<xhtml:code>http://localhost:8080/contact</xhtml:code>. We get a 404 now!</xhtml:p>
<xhtml:p><xhtml:img src="/images/screencasts/2012-09-19-zf2-module-screencast-03-config.png" alt=""/> <xhtml:img src="/images/screencasts/2012-09-19-zf2-module-screencast-04-404.png" alt=""/></xhtml:p>
<xhtml:p>Now, let's submit the form. I'll fill in some information; it's
asking for my email address, a subject line, and a message, as well
as for me to solve a simple CAPTCHA. Once I've done all that, I can
send it.</xhtml:p>
<xhtml:p>If all is well, we should now have a mail file in our data
directory. Let's check.</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ ls -l data/mail/
</xhtml:code></xhtml:pre>
<xhtml:p>And now let's look at it.</xhtml:p>
<xhtml:pre><xhtml:code class="language-bash hljs bash" data-lang="bash">$ cat data/mail/ZendMail_1347989389_1009740165.tmp
Date: Tue, 18 Sep 2012 12:29:49 -0500
From: me@mwop.net
Reply-To: me@mwop.net
Subject: [Contact Form] Suspense!

Suspenseful, isn<xhtml:span class="hljs-string">'t it?
</xhtml:span></xhtml:code></xhtml:pre>
<xhtml:p>Looks good!</xhtml:p>
<xhtml:p>Zend Framework 2 provides a wonderful modular architecture that
will enable an ecosystem of 3rd party modules that should save you
time and energy when developing your applications. I've
demonstrated a simple one, a contact form, but many, many more
already exist, and with a stable release now available, you should
see that number grow. This is truly a wonderful step forward for
developers, and I hope you find it as exciting as I do.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2012-09-19-zf2-module-screencast.html">ZF2
Modules Quickstart (Screencast)</xhtml:a> was originally published
<xhtml:time class="dt-published" datetime="2012-09-19T13:10:00-05:00">19
September 2012</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[On Microframeworks]]></title>
    <published>2012-08-17T11:00:00-05:00</published>
    <updated>2012-08-17T11:00:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2012-08-17-on-microframeworks.html"/>
    <id>https://mwop.net/blog/2012-08-17-on-microframeworks.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>A number of months ago, <xhtml:a href="http://funkatron.com/">Ed
Finkler</xhtml:a> started a discussion in the PHP community about
<xhtml:a href="http://microphp.org/">"MicroPHP"</xhtml:a>; to summarize, the
movement is about:</xhtml:p>
<xhtml:ul>
<xhtml:li>Building small, single-purpose libraries.</xhtml:li>
<xhtml:li>Using small things that work together to solve larger
problems.</xhtml:li>
</xhtml:ul>
<xhtml:p>I think there are some really good ideas that have come out of
this, and also a number of questionable practices<xhtml:sup id="t1"><xhtml:a href="#f1">1</xhtml:a></xhtml:sup>.</xhtml:p>
<xhtml:p>One piece in particular I've focussed on is the concept of
so-called “microframeworks”.</xhtml:p>
<xhtml:h2>What is a microframework?</xhtml:h2>
<xhtml:p>PHP has had microframeworks for quite some time<xhtml:sup id="t2"><xhtml:a href="#f2">2</xhtml:a></xhtml:sup>, though I only really first saw the
term being used around 3 years ago. The “grand-daddy” of modern-day
microframeworks can actually be traced to Ruby, however, and
specifically <xhtml:a href="http://www.sinatrarb.com">Sinatra</xhtml:a>.</xhtml:p>
<xhtml:p>Sinatra is not so much a framework as it is a domain-specific
language (DSL). The language and structure it created, however,
have been re-created in the vast majority of microframeworks you
see currently in the PHP arena. Specifically, it describes how to
map HTTP request methods and paths to the code that will handle
them. It borrowed route matching ideas from <xhtml:a href="http://rubyonrails.org/">Ruby on Rails</xhtml:a>, and relied on the fact
that Ruby uses the last value of a block as the return value.</xhtml:p>
<xhtml:p>As some simple examples:</xhtml:p>
<xhtml:pre><xhtml:code class="language-ruby hljs ruby" data-lang="ruby">get <xhtml:span class="hljs-string">'/hello/:name'</xhtml:span> <xhtml:span class="hljs-keyword">do</xhtml:span> <xhtml:span class="hljs-params">|n|</xhtml:span>
    <xhtml:span class="hljs-string">"Hello <xhtml:span class="hljs-subst">#{n}</xhtml:span>!"</xhtml:span>
<xhtml:span class="hljs-keyword">end</xhtml:span>

post <xhtml:span class="hljs-string">'/address'</xhtml:span>
    <xhtml:span class="hljs-comment"># create address</xhtml:span>
<xhtml:span class="hljs-keyword">end</xhtml:span>

put <xhtml:span class="hljs-string">'/address/:id'</xhtml:span> <xhtml:span class="hljs-params">|i|</xhtml:span>
    <xhtml:span class="hljs-comment"># update address</xhtml:span>
<xhtml:span class="hljs-keyword">end</xhtml:span>

get <xhtml:span class="hljs-string">'/feed.?:format?'</xhtml:span>, <xhtml:span class="hljs-symbol">:provides</xhtml:span> =&gt; [<xhtml:span class="hljs-string">'rss'</xhtml:span>, <xhtml:span class="hljs-string">'atom'</xhtml:span>, <xhtml:span class="hljs-string">'xml'</xhtml:span>] <xhtml:span class="hljs-keyword">do</xhtml:span>
    builder <xhtml:span class="hljs-symbol">:feed</xhtml:span>
<xhtml:span class="hljs-keyword">end</xhtml:span>
</xhtml:code></xhtml:pre>
<xhtml:p>The language is expressive, and allows the developer to focus on
two things:</xhtml:p>
<xhtml:ul>
<xhtml:li>What are the specific entry points (URIs) for the
application?</xhtml:li>
<xhtml:li>What needs to be done for each specific entry point?</xhtml:li>
</xhtml:ul>
<xhtml:p>I'd argue that the above two points are the defining
characteristics of modern microframeworks. Typically, the entry
points are given the term "routing", and the second corresponds to
"controllers".</xhtml:p>
<xhtml:h2>PHP implementations</xhtml:h2>
<xhtml:p>I'd argue one of the earliest microframework implementations,
though it wasn't termed as such, was <xhtml:a href="http://dev.horde.org/routes/">Horde Routes</xhtml:a><xhtml:sup id="t3"><xhtml:a href="#f3">3</xhtml:a></xhtml:sup> (which was itself inspired by
<xhtml:a href="http://routes.readthedocs.org/en/latest/index.html">Python
Routes</xhtml:a>, in turn inspired by the Rails routing system, like
Sinatra). It follows the two principles I outlined above: it allows
defining routes (entry points), and mapping them to controllers.
Controllers for Routes are simply classes, and a route must provide
both a controller and an action in the match, with the latter
corresponding to a method on the controller class.</xhtml:p>
<xhtml:p>Since around 2009, I've seen an increasing number of new PHP
microframeworks<xhtml:sup id="t4"><xhtml:a href="#f4">4</xhtml:a></xhtml:sup> that follow
in the steps of Sinatra and Horde. In the various implementations
I've looked at, instead of using a DSL, the authors have all opted
for either a procedural or OOP interface. Starting with PHP 5.3,
most authors have also primarily targetted any PHP callable as a
controller, favoring callbacks specifically. The fundamental ideas
remain the same as Sinatra, however:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-comment">/* Procedural */</xhtml:span>
get(<xhtml:span class="hljs-string">'/hello/:name'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($n)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-string">"Hello {$n}!"</xhtml:span>;
});

post(<xhtml:span class="hljs-string">'/address'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">()</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-comment">// create address</xhtml:span>
});

put(<xhtml:span class="hljs-string">'/address/:id'</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($i)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-comment">// update address</xhtml:span>
});

get(<xhtml:span class="hljs-string">'/feed.?:format?'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span><xhtml:span class="hljs-params">($feed, $format)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">return</xhtml:span> builder($feed, $format);
});

<xhtml:span class="hljs-comment">/* OOP */</xhtml:span>
$app-&gt;get(<xhtml:span class="hljs-string">'/hello/:name'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($n)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-string">"Hello {$n}!"</xhtml:span>;
});

$app-&gt;post(<xhtml:span class="hljs-string">'/address'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">()</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-comment">// create address</xhtml:span>
});
end

$app-&gt;put(<xhtml:span class="hljs-string">'/address/:id'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($i)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-comment">// update address</xhtml:span>
});

$app-&gt;get(<xhtml:span class="hljs-string">'/feed.?:format?'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($feed, $format)</xhtml:span> <xhtml:span class="hljs-title">use</xhtml:span> <xhtml:span class="hljs-params">($app)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-keyword">return</xhtml:span> $app-&gt;builder($feed, $format);
})-&gt;constraints([<xhtml:span class="hljs-string">'format'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'/^(rss|atom|xml)$/'</xhtml:span>]);
</xhtml:code></xhtml:pre>
<xhtml:p>One key difference I've witnessed in the implementations is
surrounding how route matches are passed to the callback. In the
examples above, they are passed as individual arguments to the
handler. Some, however, opt for an approach more like Sinatra,
which passes a single "params" argument into the scope of the
handler. This approach tends to be more expedient both from an
implementation standpoint as well as a performance standpoint, as
it does not require reflection to determine name and position of
arguments, and makes handling wildcard arguments simpler. I've seen
this latter approach handled several ways:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-comment">// Pass in route match parameters as an argument.</xhtml:span>
$app-&gt;get(<xhtml:span class="hljs-string">'/feed.:format'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($params)</xhtml:span> </xhtml:span>{
    $format = $params[<xhtml:span class="hljs-string">'format'</xhtml:span>];
});

<xhtml:span class="hljs-comment">// Pass in the $app instance, and retrieve route </xhtml:span>
<xhtml:span class="hljs-comment">// match parameters from it.</xhtml:span>
$app-&gt;get(<xhtml:span class="hljs-string">'/feed.:format'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($app)</xhtml:span> </xhtml:span>{
    $format = $app-&gt;params(<xhtml:span class="hljs-string">'format'</xhtml:span>);
});

<xhtml:span class="hljs-comment">// Curry in the $app instance when desired, and </xhtml:span>
<xhtml:span class="hljs-comment">// retrieve route match parameters from it.</xhtml:span>
$app-&gt;get(<xhtml:span class="hljs-string">'/feed.:format'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">()</xhtml:span> <xhtml:span class="hljs-title">use</xhtml:span> <xhtml:span class="hljs-params">($app)</xhtml:span> </xhtml:span>{
    $format = $app-&gt;params(<xhtml:span class="hljs-string">'format'</xhtml:span>);
});
</xhtml:code></xhtml:pre>
<xhtml:p>Another difference I've seen is in how route constraints,
defaults, and names are handled. The most elegant solutions usually
allow chaining method calls in order to alter this data:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php">$app-&gt;get(<xhtml:span class="hljs-string">'/feed.:format'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($app)</xhtml:span> </xhtml:span>{
    <xhtml:span class="hljs-comment">// ...</xhtml:span>
})-&gt;constraints([<xhtml:span class="hljs-string">'format'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'/^(atom|xml|json)$/'</xhtml:span>])
  -&gt;name(<xhtml:span class="hljs-string">'feed'</xhtml:span>);
</xhtml:code></xhtml:pre>
<xhtml:p>One common feature I've seen is the ability to generate URLs
based on the defined routes. Most commonly, this is a function or
method <xhtml:code>urlTo()</xhtml:code>, which takes a route name, and an
associative array of replacements.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">echo</xhtml:span> $app-&gt;urlTo(<xhtml:span class="hljs-string">'feed'</xhtml:span>, [<xhtml:span class="hljs-string">'format'</xhtml:span> =&gt; <xhtml:span class="hljs-string">'atom'</xhtml:span>]);
</xhtml:code></xhtml:pre>
<xhtml:p>That's it in a nutshell: the ability to match HTTP request
methods and path information, and map it to controllers/handlers,
and to generate URLs based on those present in the application.</xhtml:p>
<xhtml:h2>What are they good for?</xhtml:h2>
<xhtml:p>In my research and experience, microframeworks have three
typical use cases:</xhtml:p>
<xhtml:ol>
<xhtml:li><xhtml:strong>Prototyping.</xhtml:strong> Because of their simplicity,
microframeworks are fantastic for prototyping a basic website. Very
often, in the early stages of a site, you have a limited number of
pages, and most often simply need to render a template with limited
variable substitutions. Microframeworks are a perfect fit for
this.</xhtml:li>
<xhtml:li><xhtml:strong>APIs</xhtml:strong>. API needs are usually quite
well-defined, and often involve a small, finite number of URLs. The
logic required is usually already encapsulated in business objects,
so the application layer is simply for filtering and returning a
representation. Microframeworks again offer a nice fit.</xhtml:li>
<xhtml:li><xhtml:strong>Small, mostly static sites</xhtml:strong>. Similar to the
first point, if you know the site will be relatively small and
mostly static, then the minimal overhead of a microframework is
often a good fit.</xhtml:li>
</xhtml:ol>
<xhtml:h2>Where do microframeworks fail?</xhtml:h2>
<xhtml:p>Because of the rather declarative nature of microframeworks, and
the typically 1:1 mapping of a route to a controller,
microframeworks do not tend to promote code re-use. Additionally,
this extends to how microframework applications are organized:
usually, there are no clear guidelines on how to organize routes
and controllers, much less separate them into multiple files. This
can lead to maintenance issues as the application grows, as well as
logistical issues whenever you need to add new routes and
controllers (do they go at the top, or bottom? are there other
routes that could potentially match as well? etc.).</xhtml:p>
<xhtml:p>Additionally, though many frameworks offer ways to alter the
workflow of the application either via hooks, events, or
“middleware”<xhtml:sup id="t5"><xhtml:a href="#f5">5</xhtml:a></xhtml:sup>, most of these
are limited in scope, often non-reusable, and often non-stackable.
As such, comprehensive manipulation of the application workflow is
out of reach.</xhtml:p>
<xhtml:p>One other area that is overlooked, however, is one I find
curious, particularly in light of the MicroPHP movement: so much of
the underlying plumbing is basically the same, yet every
microframework re-implements it. Specifically:</xhtml:p>
<xhtml:ul>
<xhtml:li>Routing is basically the same across most implementations,
following the same basic specifications outlined in Rails. There
are very few differences in the public APIs.</xhtml:li>
<xhtml:li>Request and Response object abstraction is largely the same as
well, providing access to query/post/cookie/session/etc. parameters
through roughly equivalent APIs.</xhtml:li>
<xhtml:li>Many implement their own view layers.<xhtml:sup id="t6"><xhtml:a href="#f6">6</xhtml:a></xhtml:sup></xhtml:li>
</xhtml:ul>
<xhtml:p>Most of this code should be considered commodity code at this
point. There are several outstanding view layers and templating
engines available (Smarty, Twig, Savant, <xhtml:code>Zend\View</xhtml:code>).
Standalone routing libraries exist such as Horde Routes, and even
those bundled with frameworks are often available separately via
Composer or Pyrus; the same is true with Request and Response
object abstraction. It seems to me that a few microframework
authors should be working on abstracting these concerns, and then
focussing their efforts on differentiators in their own
microframeworks.</xhtml:p>
<xhtml:h2>An experiment</xhtml:h2>
<xhtml:p>Building on my last point, I looked at the APIs of <xhtml:a href="http://limonade-php.github.com/">Limonade</xhtml:a> and <xhtml:a href="http://www.slimframework.com/">Slim Framework</xhtml:a>, and built up a
specification for a microframework. I then matched as many pieces
of it as possible to existing components in <xhtml:a href="http://packages.zendframework.com/">ZF2</xhtml:a>, and started
building.</xhtml:p>
<xhtml:p>In a matter of a few hours, I had written up a complete test
suite<xhtml:sup id="t7"><xhtml:a href="#f7">7</xhtml:a></xhtml:sup> and all code for a
microframework, featuring the following (this is basically the
testdox output from the unit test suite):</xhtml:p>
<xhtml:ul>
<xhtml:li>Lazy loads request</xhtml:li>
<xhtml:li>Lazy loads response</xhtml:li>
<xhtml:li>Request is injectible</xhtml:li>
<xhtml:li>Response is injectible</xhtml:li>
<xhtml:li>Halt should raise halt exception</xhtml:li>
<xhtml:li>Response should contain status provided to halt</xhtml:li>
<xhtml:li>Response should contain message provided to halt</xhtml:li>
<xhtml:li>Stop should raise halt exception</xhtml:li>
<xhtml:li>Response should remain unaltered after stop</xhtml:li>
<xhtml:li>Redirect should raise halt exception</xhtml:li>
<xhtml:li>Redirect should set 302 response status by default</xhtml:li>
<xhtml:li>Redirect should set response status based on provided status
code</xhtml:li>
<xhtml:li>Redirect should set location header</xhtml:li>
<xhtml:li>Map creates a segment route when provided with a string
route</xhtml:li>
<xhtml:li>Map can receive a route object</xhtml:li>
<xhtml:li>Passing invalid route raises exception</xhtml:li>
<xhtml:li>Map can receive a callable</xhtml:li>
<xhtml:li>Passing invalid controller to route does not immediately raise
exception</xhtml:li>
<xhtml:li>Accessing invalid controller raises exception</xhtml:li>
<xhtml:li>Passing invalid method to route via method raises
exception</xhtml:li>
<xhtml:li>Can set methods route responds to singly</xhtml:li>
<xhtml:li>Can set methods route responds to as array</xhtml:li>
<xhtml:li>Can set methods route responds to as multiple arguments</xhtml:li>
<xhtml:li>Can specify additional method types to respond to</xhtml:li>
<xhtml:li>Can specify route name</xhtml:li>
<xhtml:li>Adding route using method type creates route that responds to
that method type</xhtml:li>
<xhtml:li>Running with no matching routes raises page not found
exception</xhtml:li>
<xhtml:li>Routing sets list of named routes</xhtml:li>
<xhtml:li>Routing sets lists of routes by method</xhtml:li>
<xhtml:li>Successful routing dispatches controller</xhtml:li>
<xhtml:li>Unsuccessful routing triggers 404 event</xhtml:li>
<xhtml:li>Calling halt triggers halt event</xhtml:li>
<xhtml:li>Invalid controller triggers 501 event</xhtml:li>
<xhtml:li>Exception raised in controller triggers 500 event</xhtml:li>
<xhtml:li>Can pass to next matching route</xhtml:li>
<xhtml:li>Url for helper assembles url based on name provided</xhtml:li>
<xhtml:li>Url for helper assembles url based on name and params
provided</xhtml:li>
<xhtml:li>Url for helper assembles url based on current route match when
no name provided</xhtml:li>
<xhtml:li>Composes logger instance by default</xhtml:li>
<xhtml:li>Can inject specific logger instance</xhtml:li>
<xhtml:li>Mustache view is used by default</xhtml:li>
<xhtml:li>Can inject alternate view instance</xhtml:li>
<xhtml:li>Render renders a template to the response</xhtml:li>
<xhtml:li>View model returns mustache view model by default</xhtml:li>
<xhtml:li>Subsequent calls to view model return separate instances</xhtml:li>
<xhtml:li>Can provide view model prototype</xhtml:li>
</xhtml:ul>
<xhtml:p>I utilized ZF2's routing library from its MVC component, the
request and response objects from its HTTP component, its Log
component, and the Session component. These had a few other
dependencies, but nothing terribly onerous.</xhtml:p>
<xhtml:p>For the view, I used my own <xhtml:a href="http://weierophinney.github.com/phly_mustache">phly_mustache</xhtml:a>,
and provided a basic "view model" implementation that receives the
application instance, thus allowing the ability to call application
helpers (such as url generation).</xhtml:p>
<xhtml:p>To make installation simple, I used <xhtml:a href="http://getcomposer.org">Composer</xhtml:a> to manage my dependencies on
specific ZF2 components and for <xhtml:code>phly_mustache</xhtml:code>. The
microframework contains only the code it needs to get its work
done, leveraging the work of others whenever possible.</xhtml:p>
<xhtml:p>This post is not meant as a way to announce a new
microframework, however.<xhtml:sup id="t8"><xhtml:a href="#f8">8</xhtml:a></xhtml:sup> The
point of the experiment was to prove something: microframeworks are
trivially easy to write, <xhtml:em>particularly if you follow the
principals of MicroPHP, and re-use existing code</xhtml:em>. Just because
code comes from a framework or a third-party library does not make
it suspect or inferior; in fact, whenever possible, you should
leverage such code so you can focus on <xhtml:em>writing awesome
applications</xhtml:em>.</xhtml:p>
<xhtml:h2>Lessons learned</xhtml:h2>
<xhtml:p>I really like microframeworks for specific problems:
prototyping, APIs, and small, simple sites. I think they are
ideally suited for these tasks. That said, I'd love to see some
solid libraries targetting the fundamental, shared aspects of these
efforts: routing, request and response abstraction, etc. With
dependency management tools such as Composer and Pyrus, having
required dependencies is not a big deal anymore, and re-use should
be encouraged.</xhtml:p>
<xhtml:p>Also, writing a microframework is an excellent coding exercise.
It helps a developer appreciate the complexities of abstraction
while limiting the number of moving parts. I highly recommend it as
an exercise — but do it using available components, and be prepared
to throw it away and instead collaborate with others, or adopt
something which better solves both the problems you have and the
problems you anticipate.</xhtml:p>
<xhtml:p>In sum: <xhtml:em>Use the right tool for the job</xhtml:em>. If you foresee
expanding requirements in your project's future, you may want to
evaluate a full-stack framework,<xhtml:sup id="t9"><xhtml:a href="#f9">9</xhtml:a></xhtml:sup> or consider building something robust that suits
your specific project's needs. Use microframeworks where and when
they make sense.</xhtml:p>
<xhtml:h4>Afterword</xhtml:h4>
<xhtml:p>I'm well aware that Fabien Potencier has written <xhtml:a href="http://fabien.potencier.org/article/50/create-your-own-framework-on-top-of-the-symfony2-components-part-1">
a comprehensive series of posts on creating a microframework using
Symfony 2 components</xhtml:a>. I deliberately chose not to read them
until (a) ZF2 was almost ready to release, and (b) I'd had a chance
to formulate my own opinions on microframeworks. They're an
excellent read, however, and show a nice progression of development
from flat PHP to a fully functional microframework; click the link
and see for yourself.</xhtml:p>
<xhtml:h4>Footnotes</xhtml:h4>
<xhtml:ul>
<xhtml:li><xhtml:sup id="f1"><xhtml:a href="#t1">1</xhtml:a></xhtml:sup> In particular, I feel
that the movement (a) disparages components from larger libraries
simply because they originate from a larger library, and (b)
distrust any code that has additional dependencies. This latter I
find truly puzzling, as I'd think it fits the idea of “use small
things that work together to solve larger problems.” If the code
solves a particular problem and allows you to focus on a larger
problem, where it originates and the number of dependencies should
not be an issue.</xhtml:li>
<xhtml:li><xhtml:sup id="f2"><xhtml:a href="#t2">2</xhtml:a></xhtml:sup> In fact, my first foray
into MVC in PHP was writing a clone of Perl's <xhtml:a href="http://cgi-app.org/">CGI::Application</xhtml:a>, which in many ways is
also a microframework.</xhtml:li>
<xhtml:li><xhtml:sup id="f3"><xhtml:a href="#t3">3</xhtml:a></xhtml:sup> Trivia: Both authors of
Horde Routes worked at Zend when I first started at the company,
and Mike Naberezny wrote the very first lines of code for Zend
Framework.</xhtml:li>
<xhtml:li><xhtml:sup id="f4"><xhtml:a href="#t4">4</xhtml:a></xhtml:sup> I swear, you see new
ones on Github daily, and on <xhtml:a href="http://phpdeveloper.org/">PHP
Developer</xhtml:a> at least once a week.</xhtml:li>
<xhtml:li><xhtml:sup id="f5"><xhtml:a href="#t5">5</xhtml:a></xhtml:sup> <xhtml:a href="http://www.slimframework.com">Slim</xhtml:a> has this concept.
Basically, any callables placed between the route string and the
last callable when defining a route — i.e., the “middle” arguments,
and thus middleware — will be executed in order prior to attempting
to execute the controller.</xhtml:li>
<xhtml:li><xhtml:sup id="f6"><xhtml:a href="#t6">6</xhtml:a></xhtml:sup> <xhtml:a href="http://www.slimframework.com">Slim</xhtml:a> is an outlier here, as it
utilizes <xhtml:a href="http://twig.sensiolabs.org/">Twig</xhtml:a> by
default.</xhtml:li>
<xhtml:li><xhtml:sup id="f7"><xhtml:a href="#t7">7</xhtml:a></xhtml:sup> I'm sure that my TDD
experiment will warm the soul of <xhtml:a href="http://www.littlehart.net/atthekeyboard/">the Grumpy
Programmer</xhtml:a>.</xhtml:li>
<xhtml:li><xhtml:sup id="f8"><xhtml:a href="#t8">8</xhtml:a></xhtml:sup> That said, if you want
to look at the results, you can <xhtml:a href="http://github.com/weierophinney/phlyty">find Phlyty on
Github</xhtml:a>.</xhtml:li>
<xhtml:li><xhtml:sup id="f9"><xhtml:a href="#t9">9</xhtml:a></xhtml:sup> As you may guess, I'm
biased towards <xhtml:a href="http://framework.zend.com/">Zend
Framework</xhtml:a>. However, you should always carefully evaluate a
framework against your project's needs.</xhtml:li>
</xhtml:ul>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2012-08-17-on-microframeworks.html">On
Microframeworks</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2012-08-17T11:00:00-05:00">17 August
2012</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[ZF2's New Controller::init()]]></title>
    <published>2012-07-30T15:40:00-05:00</published>
    <updated>2012-07-30T21:00:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2012-07-30-the-new-init.html"/>
    <id>https://mwop.net/blog/2012-07-30-the-new-init.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>In Zend Framework 1, controller's had an <xhtml:code>init()</xhtml:code>
method, which was called after the controller was instantiated. The
reason for it was to encourage developers not to override the
constructor, and thus potentially break some of the functionality
(as a number of objects were injected via the constructor).
<xhtml:code>init()</xhtml:code> was useful for doing additional object
initialization.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">MyController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">Zend_Controller_Action</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">init</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-comment">// do some stuff!</xhtml:span>
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>But this feature is missing from ZF2; how can we accomplish this
sort of pattern?</xhtml:p>
<xhtml:h2>Constructor Overriding</xhtml:h2>
<xhtml:p>Why didn't we add the <xhtml:code>init()</xhtml:code> method in Zend
Framework 2? Because we don't have a constructor by default, and
also to reduce overall method calls; if a controller won't be
overriding the method, there's no reason to make the call in the
first place. So, that means, in ZF2, unlike ZF1, to do the same
thing, you can simply define a constructor in your controller:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractActionController</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">MyController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractActionController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">__construct</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-comment">// do some stuff!</xhtml:span>
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>Except there's one specific and often-needed use case where this
fails: if you want to wire listeners to the controller's event
manager.</xhtml:p>
<xhtml:h2>Events</xhtml:h2>
<xhtml:p>Why does this fail with the event manager? Because when we're in
the constructor, we don't yet have an <xhtml:code>EventManager</xhtml:code>
instance! The event manager instance is injected after
instantiation. As such, we need to attach to it once we know we
have an event manager. Which is… when it's set. This can be done
very simply by overriding the <xhtml:code>setEventManager()</xhtml:code>
method. In the next example, we'll define a listener for the
"dispatch" event that redirects if certain criteria is not met.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">EventManager</xhtml:span>\<xhtml:span class="hljs-title">EventManagerInterface</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Mvc</xhtml:span>\<xhtml:span class="hljs-title">Controller</xhtml:span>\<xhtml:span class="hljs-title">AbstractActionController</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">MyController</xhtml:span> <xhtml:span class="hljs-keyword">extends</xhtml:span> <xhtml:span class="hljs-title">AbstractActionController</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">setEventManager</xhtml:span><xhtml:span class="hljs-params">(EventManagerInterface $events)</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">parent</xhtml:span>::setEventManager($events);

        $controller = <xhtml:span class="hljs-keyword">$this</xhtml:span>;
        $events-&gt;attach(<xhtml:span class="hljs-string">'dispatch'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($e)</xhtml:span> <xhtml:span class="hljs-title">use</xhtml:span> <xhtml:span class="hljs-params">($controller)</xhtml:span> </xhtml:span>{
            $request = $e-&gt;getRequest();
            $method  = $request-&gt;getMethod();
            <xhtml:span class="hljs-keyword">if</xhtml:span> (!in_array($method, <xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-string">'PUT'</xhtml:span>, <xhtml:span class="hljs-string">'DELETE'</xhtml:span>, <xhtml:span class="hljs-string">'PATCH'</xhtml:span>))) {
                <xhtml:span class="hljs-comment">// nothing to do</xhtml:span>
                <xhtml:span class="hljs-keyword">return</xhtml:span>;
            }

            <xhtml:span class="hljs-keyword">if</xhtml:span> ($controller-&gt;params()-&gt;fromRoute(<xhtml:span class="hljs-string">'id'</xhtml:span>, <xhtml:span class="hljs-keyword">false</xhtml:span>)) {
                <xhtml:span class="hljs-comment">// nothing to do</xhtml:span>
                <xhtml:span class="hljs-keyword">return</xhtml:span>;
            }

            <xhtml:span class="hljs-comment">// Missing identifier! Redirect.</xhtml:span>
            <xhtml:span class="hljs-keyword">return</xhtml:span> $controller-&gt;redirect()-&gt;toRoute(<xhtml:span class="hljs-comment">/* ... */</xhtml:span>);
        }, <xhtml:span class="hljs-number">100</xhtml:span>); <xhtml:span class="hljs-comment">// execute before executing action logic</xhtml:span>
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>The beauty of this is that we only override when we need to, and
we override in the specific context we're trying to influence.
Additionally, we're only registering the event listener if this
particular controller is instantiated — which helps reduce our
overall number of listeners, and thus shapes our call graph based
on the controller invoked.</xhtml:p>
<xhtml:h2>Other dependencies</xhtml:h2>
<xhtml:p>As you'll likely note, the event manager is not the only case
where you may need to follow a similar pattern. Any time your
initialization logic may be based on a dependency, you'll want to
override the setter in which that dependency is injected.</xhtml:p>
<xhtml:p><xhtml:em>Got any ZF2 tips of your own to share? Blog them!</xhtml:em></xhtml:p>
<xhtml:h2>Update: ServiceManager</xhtml:h2>
<xhtml:p>A few folks in the comments were remarking that the felt that
omitting the <xhtml:code>init()</xhtml:code> method makes it harder for
developers to identify when and where to do initialization logic,
particularly when you may be working with multiple
dependencies.</xhtml:p>
<xhtml:p>Which made me realize there's another place I missed, one that's
potentially even better suited to initialization: the
<xhtml:code>ServiceManager</xhtml:code>.</xhtml:p>
<xhtml:p>Basically, if you find yourself having complex initialization
needs, or many dependencies, you should be building a factory for
your controller, and wiring it to the <xhtml:code>ServiceManager</xhtml:code>.
This can happen in one of several places, but my preference is in
my module's <xhtml:code>Module</xhtml:code> class, in the
<xhtml:code>getControllerConfig()</xhtml:code> method. This method returns
configuration for the controller manager that instantiates,
validate, and injects controllers; it's basically a type of
<xhtml:code>ServiceManager</xhtml:code>, and, in fact, has access to the main
application's instance. I'll take the previous example, and wire it
in the context of a factory:</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">My</xhtml:span>

<xhtml:span class="hljs-title">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">EventManager</xhtml:span>\<xhtml:span class="hljs-title">EventManagerInterface</xhtml:span>;

<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">Module</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-comment">/*
     * Assume some other methods, such as getConfig(), etc.
     * Also assume that a route will return a controller named
     * "My\Controller\My" which we assume will reference a controller
     * within our current namespace.
     */</xhtml:span>

    <xhtml:span class="hljs-keyword">public</xhtml:span> <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-title">getControllerConfig</xhtml:span><xhtml:span class="hljs-params">()</xhtml:span>
    </xhtml:span>{
        <xhtml:span class="hljs-keyword">return</xhtml:span> <xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-string">'factories'</xhtml:span> =&gt; <xhtml:span class="hljs-keyword">array</xhtml:span>(
            <xhtml:span class="hljs-string">'My\Controller\My'</xhtml:span> =&gt; <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($controllers)</xhtml:span> </xhtml:span>{
                $services   = $controllers-&gt;getServiceLocator();
                $controller = <xhtml:span class="hljs-keyword">new</xhtml:span> Controller\MyController();
                $events     = $services-&gt;get(<xhtml:span class="hljs-string">'EventManager'</xhtml:span>)

                $events-&gt;attach(<xhtml:span class="hljs-string">'dispatch'</xhtml:span>, <xhtml:span class="hljs-function"><xhtml:span class="hljs-keyword">function</xhtml:span> <xhtml:span class="hljs-params">($e)</xhtml:span> <xhtml:span class="hljs-title">use</xhtml:span> <xhtml:span class="hljs-params">($controller)</xhtml:span> </xhtml:span>{
                    $request = $e-&gt;getRequest();
                    $method  = $request-&gt;getMethod();
                    <xhtml:span class="hljs-keyword">if</xhtml:span> (!in_array($method, <xhtml:span class="hljs-keyword">array</xhtml:span>(<xhtml:span class="hljs-string">'PUT'</xhtml:span>, <xhtml:span class="hljs-string">'DELETE'</xhtml:span>, <xhtml:span class="hljs-string">'PATCH'</xhtml:span>))) {
                        <xhtml:span class="hljs-comment">// nothing to do</xhtml:span>
                        <xhtml:span class="hljs-keyword">return</xhtml:span>;
                    }

                    <xhtml:span class="hljs-keyword">if</xhtml:span> ($controller-&gt;params()-&gt;fromRoute(<xhtml:span class="hljs-string">'id'</xhtml:span>, <xhtml:span class="hljs-keyword">false</xhtml:span>)) {
                        <xhtml:span class="hljs-comment">// nothing to do</xhtml:span>
                        <xhtml:span class="hljs-keyword">return</xhtml:span>;
                    }

                    <xhtml:span class="hljs-comment">// Missing identifier! Redirect.</xhtml:span>
                    <xhtml:span class="hljs-keyword">return</xhtml:span> $controller-&gt;redirect()-&gt;toRoute(<xhtml:span class="hljs-comment">/* ... */</xhtml:span>);
                }, <xhtml:span class="hljs-number">100</xhtml:span>); <xhtml:span class="hljs-comment">// execute before executing action logic</xhtml:span>

                $controller-&gt;setEventManager($events);
                <xhtml:span class="hljs-keyword">return</xhtml:span> $controller;
            };
        ));
    }
}
</xhtml:code></xhtml:pre>
<xhtml:p>The above will create the controller, grab an event manager
instance, attach the listener, and then inject the event manager
into the controller. If you wanted to do more complex work, you
definitely could — and this would be the place to do it.</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2012-07-30-the-new-init.html">ZF2's New
Controller::init()</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2012-07-30T15:40:00-05:00">30 July
2012</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by
<xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew
Weier O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
  <entry xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <title type="html"><![CDATA[ZF2 Forms in Beta5]]></title>
    <published>2012-07-05T15:40:00-05:00</published>
    <updated>2012-07-05T15:40:00-05:00</updated>
    <link rel="alternate" type="text/html" href="https://mwop.net/blog/2012-07-02-zf2-beta5-forms.html"/>
    <id>https://mwop.net/blog/2012-07-02-zf2-beta5-forms.html</id>
    <author>
      <name>Matthew Weier O'Phinney</name>
      <email>contact@mwop.net</email>
      <uri>https://mwop.net</uri>
    </author>
    <content xmlns:xhtml="http://www.w3.org/1999/xhtml" type="xhtml">
      <xhtml:div xmlns:xhtml="http://www.w3.org/1999/xhtml"><xhtml:p>Forms are a nightmare for web development. They break the
concept of separation of concerns:</xhtml:p>
<xhtml:ul>
<xhtml:li>They have a <xhtml:em>display</xhtml:em> aspect (the actual HTML form)</xhtml:li>
<xhtml:li>They have a <xhtml:em>validation</xhtml:em> aspect</xhtml:li>
<xhtml:li>And the two mix, as you need to display validation error
messages.</xhtml:li>
</xhtml:ul>
<xhtml:p>On top of that, the submitted data is often directly related to
your domain models, causing more issues:</xhtml:p>
<xhtml:ul>
<xhtml:li>Not all elements will have a 1:1 mapping to the domain model —
buttons, CSRF protection, CAPTCHAs, etc. usually are
application-level concerns, but not domain issues. Names valid for
your domain model may not be valid names for HTML entities.</xhtml:li>
</xhtml:ul>
<xhtml:p>Add to this that the validation logic may be re-usable outside
of a forms context, and you've got a rather complex problem.</xhtml:p>
<xhtml:h2>Forms in ZF2</xhtml:h2>
<xhtml:p>Starting in 2.0.0beta4, we offerred a completely rewritten Form
component. In fact, it's not just a Form component — a new
component, InputFilter, was also added. InputFilter is a component
that provides re-usable validation and normalization logic, and can
be used with forms or your domain model. The Form component is
basically a bridge between domain models/validation and the view
layer.</xhtml:p>
<xhtml:p>However, this means a bit more complexity for the end-user. You
now must:</xhtml:p>
<xhtml:ul>
<xhtml:li>Create your form, which consists of elements and
fieldsets.</xhtml:li>
<xhtml:li>Create an input filter, consisting of inputs.</xhtml:li>
<xhtml:li>Inform the form of the input filter.</xhtml:li>
</xhtml:ul>
<xhtml:p>It's a bit of work. And there's more: we wanted to simplify the
process of getting your validated values into your domain objects.
For this, we added a concept of <xhtml:em>hydrators</xhtml:em>, which map the
validated form values to an object you <xhtml:em>bind</xhtml:em> to the form.
Now you have <xhtml:em>three</xhtml:em> pieces to keep track of — form (and its
elements), input filter (and its inputs), and a hydrator.</xhtml:p>
<xhtml:p>So, a few developers had an idea: use annotations on the domain
model objects to define these items, letting you keep it all in one
place.</xhtml:p>
<xhtml:p>While I'm not normally a fan of annotations, I immediately saw
the appeal in this particular situation.</xhtml:p>
<xhtml:h2>An Example</xhtml:h2>
<xhtml:p>Let's consider a very simple example. The following domain
object represents data for a user, and includes a variety of
elements we'd represent in a form.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">namespace</xhtml:span> <xhtml:span class="hljs-title">MyVendor</xhtml:span>\<xhtml:span class="hljs-title">Model</xhtml:span>;

<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Form</xhtml:span>\<xhtml:span class="hljs-title">Annotation</xhtml:span>;

<xhtml:span class="hljs-comment">/**
 * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Hydrator("Zend\Stdlib\Hydrator\ObjectProperty")
 * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Name("user")
 */</xhtml:span>
<xhtml:span class="hljs-class"><xhtml:span class="hljs-keyword">class</xhtml:span> <xhtml:span class="hljs-title">User</xhtml:span>
</xhtml:span>{
    <xhtml:span class="hljs-comment">/**
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Attributes({"type":"text" })
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Validator({"type":"Regex","options":{"regex":"/^[a-zA-Z][a-zA-Z0-9_-]{1,19}/"}})
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Options({"label":"Username:"})
     */</xhtml:span>
    <xhtml:span class="hljs-keyword">public</xhtml:span> $username;

    <xhtml:span class="hljs-comment">/**
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Required(false)
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Attributes({"type":"text" })
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Options({"label":"Your full name:"})
     */</xhtml:span>
    <xhtml:span class="hljs-keyword">public</xhtml:span> $fullname;

    <xhtml:span class="hljs-comment">/**
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Type("Zend\Form\Element\Email")
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Options({"label":"Your email address:"})
     */</xhtml:span>
    <xhtml:span class="hljs-keyword">public</xhtml:span> $email;

    <xhtml:span class="hljs-comment">/**
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Type("Zend\Form\Element\Url")
     * <xhtml:span class="hljs-doctag">@Annotation</xhtml:span>\Options({"label":"Your home page:"})
     */</xhtml:span>
    <xhtml:span class="hljs-keyword">public</xhtml:span> $uri;
}
</xhtml:code></xhtml:pre>
<xhtml:p>So, what does the above do?</xhtml:p>
<xhtml:ul>
<xhtml:li>The "name" annotation gives a form or element a specific
name.</xhtml:li>
<xhtml:li>The "attributes" annotation indicates what attributes to
compose into the form or element.</xhtml:li>
<xhtml:li>Similarly, the "options" annotation specifies options to
compose into an element. These typically include the label, but may
include other configuration that doesn't have an exact analog in
the HTML attributes.</xhtml:li>
<xhtml:li>The "validator" annotation indicates a validator to compose for
the input for a given element. We also ship a "filter"
annotation.</xhtml:li>
<xhtml:li>The "type" annotation indicates a class to use for that
particular form or element. In the specific cases used above, the
elements actually provide default filters and validators,
simplifying setup further!</xhtml:li>
<xhtml:li>Last, but not least, the "hydrator" annotation indicates a
<xhtml:code>Zend\Stdlib\Hydrator</xhtml:code> implementation to use to relay
data between the form and the object. I'll cover this more
shortly.</xhtml:li>
</xhtml:ul>
<xhtml:p>So, let's now turn to creating a form and consuming it.</xhtml:p>
<xhtml:pre><xhtml:code class="language-php hljs php" data-lang="php"><xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">MyVendor</xhtml:span>\<xhtml:span class="hljs-title">Model</xhtml:span>\<xhtml:span class="hljs-title">User</xhtml:span>;
<xhtml:span class="hljs-keyword">use</xhtml:span> <xhtml:span class="hljs-title">Zend</xhtml:span>\<xhtml:span class="hljs-title">Form</xhtml:span>\<xhtml:span class="hljs-title">Annotation</xhtml:span>\<xhtml:span class="hljs-title">AnnotationBuilder</xhtml:span>;

$user    = <xhtml:span class="hljs-keyword">new</xhtml:span> User();
$builder = <xhtml:span class="hljs-keyword">new</xhtml:span> AnnotationBuilder();
$form    = $builder-&gt;createForm($user);

$form-&gt;bind($user);
$form-&gt;setData($dataFromSomewhere);
<xhtml:span class="hljs-keyword">if</xhtml:span> ($form-&gt;isValid()) {
    <xhtml:span class="hljs-comment">// $user is now populated!</xhtml:span>
    <xhtml:span class="hljs-keyword">echo</xhtml:span> $form-&gt;username;
    <xhtml:span class="hljs-keyword">return</xhtml:span>;
} <xhtml:span class="hljs-keyword">else</xhtml:span> {
    <xhtml:span class="hljs-comment">// probably need to render the form now.</xhtml:span>
}
</xhtml:code></xhtml:pre>
<xhtml:p>You're not quite done, really — most likely, you'll need to
include a submit button of some sort, and it's always good practice
to include a token to prevent CSRF injections. But with the above,
you've accomplished the major headaches of setting up a form — and
using the data — with minimal fuss.</xhtml:p>
<xhtml:h2>Much more!</xhtml:h2>
<xhtml:p>The form support in ZF2 offers a ton of other features, some of
which are not specific to forms even.</xhtml:p>
<xhtml:ul>
<xhtml:li>
<xhtml:p>ZF2 supports a variety of hydration strategies, which allow you
to pass data to and from objects. The example above uses one that
suggests a 1:1 mapping between the inputs and the object
properties; other strategies include using
<xhtml:code>ArrayObject</xhtml:code>, using class mutator methods, and
more.</xhtml:p>
<xhtml:p>At this point, you can hydrate an entire form, as well as
individual fieldsets!</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>You can provide custom annotations. While this feature is not
documented yet, you can tell the <xhtml:code>AnnotationBuilder</xhtml:code>
about additional annotation classes, as well as provide listeners
for those annotations so that they can interact with the form
construction process. As an example, one contributor has already
used these features to utilize <xhtml:a href="http://doctrine-project.org">Doctrine</xhtml:a> annotations to inform
the builder about the name of a property, as well as indicate
validators. (Side note: ZF2 now uses Doctrine's annotation syntax
and parser by default.)</xhtml:p>
</xhtml:li>
<xhtml:li>
<xhtml:p>There are a number of features targetting collections, so that
your client-side code can return arbitrary numbers of a specific
fieldset type (e.g., collecting addresses for an applicant), and
the form will be able to validate each. You can <xhtml:a href="http://www.michaelgallego.fr/blog/?p=190">read more about those
features from the author himself</xhtml:a>.</xhtml:p>
</xhtml:li>
</xhtml:ul>
<xhtml:p>These features are all now available starting with the newly
released 2.0.0beta5 version, which you can grab from the <xhtml:a href="http://packages.zendframework.com/">ZF2 packages site</xhtml:a>.</xhtml:p>
<xhtml:p>I'm really excited with the solutions we've created in ZF2, and
even more excited to see people put them to use!</xhtml:p>
<xhtml:div class="h-entry"><xhtml:img class="u-photo photo" width="50" src="https://avatars0.githubusercontent.com/u/25943?v=3&amp;u=79dd2ea1d4d8855944715d09ee4c86215027fa80&amp;s=140" alt="matthew"/> <xhtml:a class="u-url u-uid p-name" href="https://mwop.net/blog/2012-07-02-zf2-beta5-forms.html">ZF2 Forms
in Beta5</xhtml:a> was originally published <xhtml:time class="dt-published" datetime="2012-07-05T15:40:00-05:00">5 July 2012</xhtml:time> on <xhtml:a href="https://mwop.net">https://mwop.net</xhtml:a> by <xhtml:a rel="author" class="p-author" href="https://mwop.net">Matthew Weier
O'Phinney</xhtml:a>.</xhtml:div>
</xhtml:div>
    </content>
  </entry>
</feed>
