Foundations of Python Network Programming

(WallPaper) #1

Chapter 10 ■ http ServerS


178


If the first three constraints of REST are achieved, then a service becomes radically transparent to the HTTP
protocol and thus to the full slate of proxies, caches, and clients, which are written to take advantage of its semantics.
Furthermore, they can do so whether the service is designed for human consumption, delivering HTML pages
bristling with forms and JavaScript (see Chapter 11), or is designed for machine consumption with succinct URLs
leading to JSON or XML representations.
But the last constraint is achieved far less often.
“Hypermedia as the engine of application state” has become contentious enough to need an acronym! While
not being singled out for special attention in Dr. Fielding’s thesis, it has since been abbreviated to “HATEOAS” in the
subsequent literature and debates. He drew attention to the constraint with a blog post “REST APIs must be hypertext-
driven” that complained about the announcement of a so-called REST API that, in fact, failed this final constraint.


http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven


There he unpacks the HATEOAS constraint into no less than six separate bullet points, of which the last is
perhaps the most sweeping. It begins, “A REST API should be entered with no prior knowledge beyond the initial URI
(bookmark) and set of standardized media types that are appropriate for the intended audience.”
This would disqualify almost all familiar HTTP-driven APIs. Whether purveyed by Google or GitHub, their
documentation nearly always seems to start a discussion of each resource type with, “Each post lives at a URL like
/post/1022/ that names the post’s unique ID.” With this maneuver, an API has departed from complete RESTfulness
and has entered a murky realm where special rules embedded in documentation, and not hypertext links, are leading
the client to the correct resource.
A fully RESTful API, by contrast, would have a single entry point. The media returned would include, perhaps, a
series of forms, one of which could be used to submit a blog post ID to learn its URL. The service itself, then, and not
human-readable documentation, would dynamically link the idea of “the post with ID 1022” with a particular path.
This encompassing concept of hypertext is, for Dr. Fielding, a crucial constraint for services aiming for decades
of use, which will be capable of supporting many generations of HTTP clients and, later, data archaeology when
the original users of an old service are all long gone. But because most of the benefits of HTTP—statelessness,
redundancy, and cache acceleration—can be gained through the first three elements alone, it appears that few
services have yet risen to the challenge of full REST compliance.


WSGI Without a Framework


Chapter 7 exhibited several patterns for writing a network service, any of which can be used to answer HTTP requests.
But there is rarely any need to write your own low-level socket code to speak the protocol. Many of the protocol details
can be delegated to your web server and, if you opt to use one, to your web framework. What is the difference between
the two?
The web server is the code that will hold a listening socket, run accept() to receive new connections, and parse
each incoming HTTP request. Without even needing to invoke your code, a server will handle cases like a client that
connects but never finishes its request and a client whose request cannot be parsed as HTTP. Some servers will also
time out and close a client socket that goes idle and rejects requests whose path or headers are unreasonably long.
Only well-formed, complete requests are passed to your framework or code by invoking the WSGI callable that you
have registered with the server. The server will typically, on its own authority, go ahead and produce HTTP response
codes (see Chapter 9) like these:


•    400 Bad Request: If the incoming HTTP request is unintelligible or exceeds a size limit you
have specified

•    500 Server Error: If your WSGI callable raises an exception instead of running successfully
to completion
Free download pdf