HTTP and its secure variant, HTTPS, are the protocols used by every web client to talk to web applications. A key part of the protocol is the HTTP method. Traditionally, web applications used a very limited set of HTTP methods. It is common for application servers, proxies and routers (such as the Heroku HTTP router) to prevent unknown methods from being used. This unnecessary constraint of the Heroku HTTP router has increasingly become a limitation to developers building modern web applications.
In the past, if you tried to use an unsupported HTTP method in your Heroku
application, clients would receive a 405 METHOD_NOT_ALLOWED
error.
As of today, that's no longer the case. The Heroku routers now accept any HTTP
method, allowing you to use newer methods that have recently
gained adoption, such as PATCH
.
Why is this important?
Many new web frameworks use recently introduced HTTP methods such as PATCH
or
even custom methods that are not yet standardized. Ruby on Rails is one such
framework. Rails has constantly evolved since its birth to always incorporate
the latest development techniques. One such evolution is happening in Rails
4 where the framework uses the PATCH
HTTP method to perform
partial updates of resources.
Before Heroku removed restrictions on HTTP method, it was not possible to
leverage this new functionality in Rails 4. Now that any method is supported,
you can take full advantage of PATCH
support in Rails 4.
Background
For the curious, a little more background is in order.
HTTP is extensible
A huge factor in HTTP's popularity has been its extensibility. HTTP is a simple
protocol that can be used for many different purposes. For instance, the
HTTP/1.1 Spec defines the following set of methods: OPTIONS
, GET
,
HEAD
, POST
, PUT
, DELETE
, TRACE
, CONNECT
.
But the spec also states that new methods can be added. In fact, a number of other RFCs have standardized additional HTTP methods, often for specific applications such as version control or calendaring. Yet in most cases, regardless of the underlying application, developers can leverage the same supporting infrastructure: load balancers, proxies, caching proxies; all designed for HTTP.
The HTTP PATCH
Method
A recent extension to HTTP is RFC5789, which introduced the PATCH
method. This method is particularly useful for web application developers, as it
standardizes a common way to make partial updates to resources. Rails 4 and many
other libraries now make use of it.
We can quickly demonstrate how it is used by deploying a basic Sinatra app to
Heroku using the quick start guide. Replace the code in
app.rb
with:
require 'sinatra'
require 'json'
class App < Sinatra::Base
# fake persistent data.
DATA = { "a" => 1, "b" => 2, "c" => 3 }
put '/data' do
# put replaces the existing resource so we simply return the new resource
new_data = JSON.parse(request.body.read)
new_data.to_json
end
patch '/data' do
# patch 'patches' the existing resource
new_data = DATA.merge(JSON.parse(request.body.read))
new_data.to_json
end
end
Once your app is deployed, perform a PATCH
and PUT
request with curl:
$ curl -X PATCH http://shiny-object-1234.herokuapp.com/data -d '{"a": 2, "b": 3}'
{"a":2,"b":3,"c":3}
$ curl -X PUT http://shiny-object-1234.herokuapp.com/data -d '{"a": 2, "b": 3}'
{"a":2,"b":3}
The PATCH
logic merges the new values into the existing data structure and
returns the whole data structure, whereas PUT
simply replaces the old data
structure with a new one. While this example doesn't persist the changes, it
demonstrates the semantic difference between these two HTTP methods.
Other HTTP methods
PATCH
is just one example of how a new HTTP method was defined, standardized
and successfully achieved widespread use. Because Heroku no longer imposes any
restrictions on HTTP methods, future extensions will work seamlessly without
requiring explicit support. This also means that the Heroku platform can be used
as a proving ground for new, non-standardized HTTP methods.
Why restrict HTTP methods in the first place?
The original motivation for application servers, proxies and HTTP routers to
restrict HTTP methods was that these intermediaries often performed more
functions than just passing through requests. For example, if an intermediary
wants to retry a failed request, it needs to understand whether a retry is safe.
POST
and PATCH
requests are generally not safe to retry while GET
, PUT
, and
DELETE
are.
Heroku's routers pass requests straight through to the application, without special handling based on the particular HTTP method; the routers therefore handle all requests the same, regardless of which method was used. This results in maximum flexibility for the application developer to use any HTTP method and fully control the semantics of each request.
For more on HTTP routing visit our Dev Center article.