Expanded HTTP Method Support

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.

Browse the blog archives or subscribe to the full-text feed.