{
    "href": "/post/2017/01/05/psr-7-vs-the-serverrequestresponse-rfc/",
    "relId": "2017/01/05/psr-7-vs-the-serverrequestresponse-rfc",
    "title": "PSR-7 vs. the Server(Request|Response) RFC",
    "author": "pmjones",
    "markup": "html",
    "tags": [
        {
            "href": "/tag/php/",
            "relId": "php",
            "title": "PHP",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        },
        {
            "href": "/tag/programming/",
            "relId": "programming",
            "title": "Programming",
            "author": null,
            "created": null,
            "updated": [],
            "markup": "markdown"
        }
    ],
    "created": "2017-01-05 16:58:27 UTC",
    "updated": [
        "2017-01-05 16:58:27 UTC"
    ],
    "html": "<p>tl;dr: PSR-7 aims to model HTTP messages, whereas the RFC aims to make some non-OO PHP functionality more OO-ish.</p>\n<hr>\n<p>I had thought the distinction between the purpose of PSR-7, and the purpose of the <a href=\"https://wiki.php.net/rfc/request_response\">server-side request/response object RFC</a>, was obvious from their descriptions. But that is apparently not the case.</p>\n<p>I would prefer to discuss the RFC entirely on its own merits, and not dwell on the various strengths and weaknesses of PSR-7. However, to reduce confusion on this topic, I am happy to take some time to expound on the differences.</p>\n<p>To understand those differences more clearly, we need to start with a history of PSR-7.</p>\n<h3 id=\"purpose-of-psr-7\">\n<a name=\"user-content-purpose-of-psr-7\" href=\"#purpose-of-psr-7\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Purpose of PSR-7</h3>\n<p>PSR-7 was born to answer the question, \u201cHow can we model HTTP messages in PHP for sending a request, and getting back a response?\u201d That is, how can we standardize the model of an HTTP request message for sending, and the model of the returned the HTTP response, when using PHP as an HTTP client?</p>\n<p>The entrance vote passed in Jan 2014 after about a year of pre-work, with Michael \u201cGuzzle\u201d Dowling as lead: <a href=\"https://groups.google.com/d/topic/php-fig/H1Lr7FYxj94/discussion\">https://groups.google.com/d/topic/php-fig/H1Lr7FYxj94/discussion</a>. You can see the original draft at <a href=\"https://github.com/php-fig/fig-standards/pull/244/files\">https://github.com/php-fig/fig-standards/pull/244/files</a>.</p>\n<p>What you\u2019ll find in the draft is one pair of request/response interfaces, descended from a message interface, with stream as message body, and no URI specification. These were designed primarily as client interfaces; all the referenced projects in the draft were client-side. (As a side note, they were mutable. Dowling said, \u201cHaving mutable and immutable messages would add a significant amount of complexity to a HTTP message PSR and would not reflect what is currently being used by a majority of PHP projects.\u201d)</p>\n<p>After 8 months, Dowling stepped down in August 2014, citing a lack of time and motivation. He also said: \u201cI don\u2019t think there\u2019s <em>one</em> way to represent HTTP messages, clients, or servers in PHP.\u201d <a href=\"https://groups.google.com/forum/#!topic/php-fig/XwFcqSmqzGk\">https://groups.google.com/forum/#!topic/php-fig/XwFcqSmqzGk</a></p>\n<p>Shortly thereafter, in September 2014, with encouragement from many (including myself), MWOP of Zend Framework <a href=\"https://groups.google.com/d/topic/php-fig/CTPRa2XP8po/discussion\">takes over PSR-7</a>. We learn that he has \u201cSencha Connect\u201d and middleware on the brain:</p>\n<blockquote>\n<p>The reason I wanted to port Connect is this: an application consists of middleware. Each middleware is a callback that accepts a request, response, and a callback called \u201cnext\u201d (which is optional, actually):</p>\n<p><code>function (request, response, next)</code></p>\n<p>\u2026</p>\n<p>I know from Michael Dowling that the original intent for PSR-7 was to define HTTP messages that could then be used in HTTP <em>clients</em>. I am here to argue that they are even more important when considering server-side applications.</p>\n</blockquote>\n<p>At this point, we see that PSR-7 has been expanded to answer a second question: \u201cHow can we model HTTP messages for receiving a request, and sending back a response?\u201d This is in addition to the original goal, but idea is the same: building a standard model of HTTP messages.</p>\n<p>(For full disclosure, note that <a href=\"https://groups.google.com/d/topic/php-fig/Y3a4hcRN610/discussion\">I became a sponsor on PSR-7 in December 2014</a>, along with Beau Simensen as the coordinator.)</p>\n<p>It is during MWOP\u2019s tenure, before the <a href=\"https://groups.google.com/d/topic/php-fig/0baLqR6Rvcg/discussion\">successful acceptance vote</a> in May 2015, that we see the PSR-7 interfaces expand in number, and become \u201cimmutable\u201d (with one intentional exception, and other unintentional exceptions).</p>\n<p>So we can see that the purpose of PSR-7 is to <a href=\"http://www.php-fig.org/psr/psr-7/\">model 2 sets of HTTP messages using 7 interfaces</a>: one set for when PHP sends a request and receives a response, and an addition set for when PHP receives a request and sends a response.</p>\n<h3 id=\"the-purpose-of-the-serverrequestresponse-rfc\">\n<a name=\"user-content-the-purpose-of-the-serverrequestresponse-rfc\" href=\"#the-purpose-of-the-serverrequestresponse-rfc\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>The Purpose of the Server(Request|Response) RFC</h3>\n<p><a href=\"https://wiki.php.net/rfc/request_response\">The proposed RFC</a> starts out by asking a different question. It is not concerned with modeling HTTP messages, whether when sending or receiving them. Instead, it asks: \u201cHow can we take the request-related superglobals in PHP, and the various response-related global functions in PHP, and encapsulate them in objects, to make them at least a little more object-oriented?\u201d Becuase the RFC begins with a different question, it leads to a different answer.</p>\n<p>You end up with a <a href=\"https://gitlab.com/pmjones/ext-request#serverrequest\">ServerRequest</a> object that exposes almost only properties, mimicking PHP\u2019s superglobals. The properties are read-only, since they represent user input that should be copied out, not changed-in-place. As a convenience, a lot of common <code>$_SERVER['HTTP_*']</code> values are parsed into more usable representations. Conceding the needs of application development, there are properties and methods for <strong>truly</strong> immutable values relating to application-specific parameters, parsed content input, and so on.</p>\n<p>You also end up wih a <a href=\"https://gitlab.com/pmjones/ext-request#serverresponse\">ServerResponse</a> object that exposes only methods, mimicking some of PHP\u2019s global functions.  Instead of emitting headers and cookies on each call to the related methods, it buffers and retains the header and cookie values until <em>you</em> decide to send them. As a collection point for those values, and for content, you can inspect the state of the object prior to sending, and modify it as needed. It has some convenience methods, not least of which includes sending content as a download, or as JSON, with the appropriate headers.</p>\n<h3 id=\"conclusion\">\n<a name=\"user-content-conclusion\" href=\"#conclusion\" class=\"headeranchor-link\" aria-hidden=\"true\"><span class=\"headeranchor\"></span></a>Conclusion</h3>\n<p>I hope this helps to clear up any confusion as to the purpose of the RFC, vs. the purpose of PSR-7. They start with different questions, and have different goals. I think it would be better to see them as orthogonal to each other at worst, and complementary at best.</p>\n<p class=\"reddit-links\">Read the Reddit discussion about this post <a href=\"https://www.reddit.com/r/PHP/comments/5m7im5/psr7_vs_the_serverrequestresponse_rfc/\">here</a>.</p>\n"
}
