Advanced Rails - Building Industrial-Strength Web Apps in Record Time

(Tuis.) #1

222 | Chapter 7: REST, Resources, and Web Services


conditionalPUTis used to prevent stale updates by makingPUTrequests conditional
on the previous state of the resource.


In other words, a conditionalPUTcontains anIf-Unmodified-SinceorIf-Matchheader
(the exact opposites of theIf-Modified-SinceandIf-None-Matchheaders, respec-
tively) with the Last-Modified date or ETag of the last known representation of that
resource. If the server’s version of the resource (before the requested update) differs
from that requested by the client, the update will be aborted and a 412 Precondition
Failed response code returned. Typical usage is as follows:


def update
@product = Product.find params[:id]
if_unmodified @product do
if @product.update_attributes params[:product]
redirect_to product_path(@product)
else
render
end
end
end

Now, before updating the product with the provided attributes, the headers will be
inspected to ensure that the client and server agree on the resource’s state before the
update. If they are the same, thePUT will proceed as usual.


Note that the typical application of this code has a race condition
betweenif_unmodifiedchecking the headers and actually performing
the update. This is unavoidable from the plugin’s standpoint, as it has
no idea what you will be doing inside the block.
To ensure that this race condition doesn’t cause problems under heavy
concurrency, you will need to wrap the entireSELECT/UPDATEseries in a
database transaction, and run the database under a transaction isola-
tion level that prevents nonrepeatable reads (such as SERIALIZABLE).

HTTP Response Status Codes


One often-overlooked part of HTT Pis the rich set of response status codes it defines.
The HTTP/1.1 RFC defines many response codes that are appropriate for document-
based interactions; this set was enriched by WebDAV with some status codes that
filled in the gaps for dynamic web applications (such as 422 Unprocessable Entity,
used when the submitted entity is semantically invalid, often as determined by
ActiveRecord validations).


HTT Presponse codes are three-digit numbers with an optional human-readable expla-
nation. The numbers are defined by RFC 2616 (for HTTP/1.1), but the text is only sug-
gested by RFC. The first digit of the numerical code indicates to which of five categories

Free download pdf