Continuing from Tuesday’s post, I’m going to continue covering my closer look into the components that affect a Rails controller. My goal with these couple of posts on controllers are to better understand the technologies involved, the reasons why, and ultimately become confident (i.e proficient) enough that future controller builds can be made intuitively, overcoming any unwary technical limitations I had in the past.
Here’s a little wikipedia to kick off our walk-thru.
An HTTP session is a sequence of network request-response transactions. An HTTP client initiates a request by establishing a Transmission Control Protocol (TCP) connection to a particular port on a server (typically port 80; see List of TCP and UDP port numbers). An HTTP server listening on that port waits for a client’s request message. Upon receiving the request, the server sends back a status line, such as “HTTP/1.1 200 OK”, and a message of its own. The body of this message is typically the requested resource, although an error message or other information may also be returned.
HTTP defines verbs for the indication of a desired action to be performed on an identified resource. If you’d like a refresher on what a resource is, check the second paragraph of this post out. The REST style provides characterization of communication between systems (a browser and a server, typically in web development) as a series of requests to which their responses are representatives of resources.
Lets go over 9 HTTP verbs to get a feel for how descriptive communicating over the web can be.
GET Requests a representation of the specified resource. Requests using GET should only retrieve data and should have no additional effect. This is how we are able to view a resource composed of data on our server.
HEAD Requests an identical response as a GET request, but without the response body, which is useful for retrieving meta-data written in response headers without having to transport the entire content. Used in HTTP caching, when a browser stores local copies of web resources for faster retrieval for times the resource is required in the future.
POST Requests that the server accept the entity enclosed within the request as supplementary of the web resource identified by the uniform resource identifier. This is the verb used by our forms to send user created form data to the database.
PUT Requests that the enclosed entity be stored under the supplied uniform resource identifier. If the URI refers to an already existing resource, it is modified. If the URI does not point to an existing resource, then the server can create the resource with that URI. This is how data from a Rails URI such as
application.com/users/45/edit can modify a resource, in this case a user’s profile. Using PUT will ‘update’ the resource.
DELETE Deletes a specified resource.
TRACE Echoes back the received request so a client can see if any modifications have been made by intermediate servers. An example of this would be a proxy server used to speed up access to resources using caching, security and/or anonymity purposes.
OPTIONS Returns the HTTP methods that the server supports for the specified URL. Here is a link to an informative post about this verb, as it is somewhat obscure.
CONNECT Converts the request connection to a transparent TCP/IP tunnel. A tunneling protocol is usually used to facilitate encrypted communication through an unencrypted proxy.
PATCH Used to apply partial modifications to a resource.
HTTP servers are required to implement GET and HEAD verbs, and whenever possible also the OPTIONS verb.
Safe Methods vs Idempotent Methods
What does an HTTP verb have to do to be safe? They are considered to be safe if they are intended only for information retrieval and refrain from changing the state of a server. HEAD, GET, OPTIONS and TRACE as we can see from our descriptions above are defined as Safe HTTP methods because they each just grab (i.e. request) data or meta-data.
In contrast POST, PUT and DELETE are intended for actions that may cause the server to change state.
The PUT and DELETE methods are defined as idempotent, meaning that multiple identical requests should have the same effect as one request. In contrast, sending an identical POST request multiple times may further affect server state.
Now that we have a little more background about HTTP request/response cycles and the verbs that characterize them, lets see how Rails looks at sessions, here’s an excerpt from the Rails Guides.
Your application has a session for each user in which you can store small amounts of data that will be persisted between requests. The session is only available in the controller and the view and can use one of a number of different storage mechanisms:
ActionDispatch::Session::CookieStore – Stores everything on the client.
ActiveRecord::SessionStore – Stores the data in a database using Active Record.
ActionDispatch::Session::CacheStore – Stores the data in the Rails cache.
ActionDispatch::Session::MemCacheStore – Stores the data in a memcached cluster (this is a legacy implementation; consider using CacheStore instead).
All session stores use a cookie to store a unique ID for each session (you must use a cookie, Rails will not allow you to pass the session ID in the URL as this is less secure).
The guides reccomend and default to ActionDispatch::Session::CookieStore. The advantages being zero setup in a new application, being very light weight, and the advantage of being tamper-proof but not encrypted. Meaning that anyone with access to it can read, but not edit, it’s contents. Rails will not accept it if it has been edited.
Without sessions, a user would have to authenticate upon each client request. With sessions, a user can make additional URI requests and have data (i.e. granted privileges, shopping cart items, etc…) stored temporarily.
HTTP being stateless just means that between request/response cycles it doesn’t remember anything. Each cycle is a single request with no threaded connection between them. Sessions are a temporary thread to communicate (by it’s ID) between the server and the client during future request/response cycles.
A session id consists of the hash value of a random string. The random string is the current time, a random number between 0 and 1, the process id number of the Ruby interpreter.
Don’t store large objects in a session, instead commit the object to the database and store the object’s id inside of the session.
Critical data shouldn’t be stored inside of a session. If a user clears cookies or closes the browser, all is lost.
We can access a session in our controller through an instance method called session. Here are some visuals from the Rails Guides:
The next section on sessions deals with The Flash, and I may or may not cover it in a future post. Here is the link if you’re interested in reading more about it.
I hope that this has been as informative for you as it was for me.
Categories: Ruby on rails