CSC/ECE 517 Spring 2015/ch1b 15 SH

From Expertiza_Wiki
Jump to navigation Jump to search

Rails 4.0 and the PATCH verb

Background

HyperText Transfer Protocol (HTTP) is the underlying protocol used by web browsers to communicate with servers. It is a standard for the messages sent by the client to request for information or a specific action from the server. A HTTP request consists of a method that tells the server what the client needs. This method is also called an action or a verb. Some commonly used HTTP verbs in the Rails context are GET, POST, PUT, PATCH and DELETE.

The Rails app receives a request from a client browser and routes it based on the request's URI and the verb (or action or method). The request then needs to be dispatched to the appropriate controller method along with the parameters/data associated with it. This is the job of the Rails router. The router can also generate paths and URLs for all the common actions for a given controller. This is the Rails default, called Resource routing.

Rails and HTTP Verbs

As mentioned above, browsers request pages or services from Rails by through a URL using a specific HTTP verb. These verbs specify an operation that is requested on a resource. A resource route associates these verbs with actions on a specific controller. In other words, it specifies a mapping between a (URL, HTTP verb) combination and a controller action.

For example, a single entry in a routing file, such as resources :recipes

creates seven default routes in the application, mapping to actions in the Recipes controller. Each action is also associated with a CRUD operation in a database. Before Rails 4.0 the routes looked like this:

HTTP Verb Path action used for GET /photos index display a list of all photos GET /photos/new new return an HTML form for creating a new photo POST /photos create create a new photo GET /photos/:id show display a specific photo GET /photos/:id/edit edit return an HTML form for editing a photo PUT /photos/:id update update a specific photo DELETE /photos/:id destroy delete a specific photo

With Rails 4.0, the entry for the update route changed to: PATCH/PUT /photos/:id photos#update update a specific photo

In the following sections, we will look at why PATCH is the correct HTTP verb to match the "update" action.


PUT and PATCH

First, we will look at how the PUT action is different from the more familiar HTTP POST. PUT is used when a resource can be updated through itself. POST is used when we do not know the actual location of the resource, like in case of a create action. For example, if we want to add a new recipe, but let the server decide where to store it, we use POST

POST /articles HTTP/1.1 
{
"title" : "",
"description" : ""
}

HTTP/1.1 201 Created Location: /recipes/124

if we want to access a recipe that we know resides at http://cookbook3.com/recipes/123, it can be done directly with a PUT action on this URL PUT /recipes/123 HTTP/1.1 { "title": "" "description":"" } (Note that the action in the example for POST above can also be done with PUT, in case the client decides the actual URL) So the PUT action can be used to request creation or an update to a resource. Rails by default uses POST for the create action, and PUT for the update action (versions before 4.0)

What is wrong with PUT

The problem seen with HTTP PUT is that it does not allow partial updates to resources. The HTTP verb PUT means "creation and replacement" at the given URL. A request to update a resource through PUT would need a complete representation of the resource for replacement.

For example, if the recipe resource has the following representation { "title": "description" "category" }

and we want to update the category field to "5", submitting only category=5 as payload via PUT to the http://cookbook3.com/recipes/:id URL does not conform to the HTTP semantics. We would need to PUT the entire recipe back with the updated value of category, which may require a GET of its current state, can get complex and would require more bandwidth. The way out of these constraints with HTTP methods is to define category as a resource by itself, and give it a URL for update, like this : http://cookbook3.com/recipe/:id/category. A PUT to this URL will now work as category=5 would be a complete representation of its resource. This approach would need us to specify routes for every field of the resource for updation. An alternative could be to use POST for partial updates, which does not have any generic semantics, and the server and client would need application-specific code to support it. We could use PATCH instead.


Enter PATCH

The HTTP method PATCH can be used to update partial resources. It was proposed as a new way to modify HTTP resources. PATCH is like PUT in that it updates a resource, but instead of replacing the entire resource with data from the payload, it applies a "diff" or a delta. While PATCH does not require the complete representation of the resource to be sent, it is not enough to send just an updated value. The payload for PATCH describes modifications to be made to that resource. The PATCH method requests that these modifications be applied to the resource identified by the URL. A diff is applied to the resource currently existing at the server to produce a new version.

PATCH /recipes/123 HTTP/1.1

[description of changes]

Note that this set of changes must be applied atomically. It should not be possible that resources are only half-modified when requested by a GET.

You can use whatever format you want as [description of changes], as far as its semantics is well-defined. That is why using PATCH to send updated values only is not suitable.

From the RFC:

The difference between the PUT and PATCH requests is reflected in the way the server processes the enclosed entity to modify the resource identified by the Request-URI. In a PUT request, the enclosed entity is considered to be a modified version of the resource stored on the origin server, and the client is requesting that the stored version be replaced. With PATCH, however, the enclosed entity contains a set of instructions describing how a resource currently residing on the origin server should be modified to produce a new version. The PATCH method affects the resource identified by the Request-URI, and it also MAY have side effects on other resources; i.e., new resources may be created, or existing ones modified, by the application of a PATCH.

One of its principles of REST is to leverage on the standardized behavior of the protocol underlying it (cite) Since PATCH follows the semantics of HTTP better than PUT, it is more RESTful.

Conclusion

References

[1]