Category Archives: software architectures

SPA : Single Page Application – What, Why and How

It’s been some time since my last post, I feel a little rusty, but I was busy working and learning new stuff. This post will be an abstract thing, and I’m going to quit thinking of a song title-like post titles from now on…

So, What is SPA? Single Page Applications or One Page Applications are something very interesting today. The idea is to have something like desktop app look-and-feel in the browser.

The common web sites work like that (using HTTP):
1. Client makes HTTP request to the server, server responds with the page.
2. User click a link on the current page – new request, new page from the server and so on.
The idea is that the client gets the information on pages, request – whole page, request whole page. But if there is a little change on the current page and we want to see that change, we will have to reload this whole page by following this model. So what to do?

Enter the AJAXAsynchronous JavaScript and XML).
I’m not going to get in the details here, but the browser’s give you the XMLHttpRequest javascript object and you can use it to make request to the server, without reloading the current page or loading a new page. With AJAX we are able to load parts of the current page from the server. Cool.
So imagine a single initial request that downloads a page. This page is the application. Everything else is AJAX requests and loading data represented in some format from the server.
So the model here is:
1. Client makes HTTP request to the server, server responds with the application.
2. The client application asks server for data and markup when it is needed.
So your page can look alike a desktop application with menu bar, status bar, tabs and screens, that are changed via javascript on user actions, the data and the markup for that are provided dynamically by the server.

 

OK, now why we need such a thing?
We can take a look back and we’ll see that the Single Page Application for the web is not a new idea, for example the Java Applets were exactly desktop apps in the browser, the Flex/Flash applications too, Microsoft has their Silverlight, etc.
We can see that people tend to use the browser for almost everything, as time passes I realize that I don’t want to install desktop applications and I want my apps to be OS independent, the browsers are getting more and more capable to be Operating System in the Operating System, OS in the OS if you want… We use Gmail (SPA), mail client (I prefer it over Thunderbird), we use Google Drive, we use Pivotal Tracker, we use e-book readers for the browser, we use MP3 players for the browser, there is the Chrome Store (Every browser tends to have something as a store for plugins and apps), there are the Chrome Book Notebooks (ahead of their time in my opinion, btw)…
Additionally, as a developer I see how the clients want more and more Single Page Applications. They are more flexible and easy to use by their employees and users.
So my thoughts are that the Single Page Applications are tightly bound to the future of the web.

 

But how to code something like this. It is not so easy as a common web site.
Yes it is not, you’ll have to write more and more Javascript or Cofeescript or something that translates to Javascript :).
But as it was for the server side in the recent past : PHP, JSP, ASP – one application is written entirely in one layer and in one file – BAD;
VS
The applications is divided to layers and files, convention over configuration, do not repeat yourself, test driven, etc – Rails, Django, Spring, Symphony, Play, etc – GOOD,
we have frameworks that will help us code a good Single Page Application now.
We have Ember JS (by some contributors to Rails), Angular JS (by Google), Can JS, Backbone, GWT, etc.
The web is growing and everything is getting more complex, the needs of the clients are changing, and there are frameworks to help us, as developers, to adapt.

So I wanted write about the Single Page Apps, because I’m doing a lot of applications like that nowadays and maybe I’ll write about Ember Js and its integration with Rails or Node’s Grunt soon… I hope you found something new in this post. Cheers until the next one!!!

PS. I didn’t forget the Websocket protocol (it is for another post).

Useful Links:

  1. Single Page Application in Wikipedia – http://en.wikipedia.org/wiki/Single-page_application
  2. Ember JS – A Framework For Creating Ambitions Web Apllications – http://emberjs.com
  3. Angular JSHTML Enhanced For Web Apps – http://angularjs.org
  4. Can JS – Build Better Apps Faster – http://canjs.com/
  5. The Bulgarian Twitter page for Ember JS – https://twitter.com/emberjsbulgaria
  6. A SPA for reading ePUB books from Chrome (offline capability), Safari, Android and Windows 8, written by me and my colleges from Astea Solutions – Livemargin Reader Beta

REST : RESTin’ in the RESTful World – part 1

Today I’m going to present to you the RESTful architecture. The concept is simple but often misunderstood. I’m a big fan of the idea, because it gives us both freedom and simplicity by just using the HTTP protocol.

REST stands for “REpresentational State Transfer” and is introduced in 2000 by Roy Fielding in his doctoral dissertation. I know quite a few people which think of REST as just using HTTP GET and POST requests to modify and read resources in given format. This is not REST, this is some kind of custom communication API. I was one of these people until I chose to read some books and articles for a change and it turned out to be quite refreshing… I’ll tell you about the RESTful architecture as I see it through my mind.

Imagine that the Web is an Universe. Universe composed of resources. These resources have unique identifiers and can be viewed through many different representations. For example in a list of comments, stored somewhere in the Web we have many comment resources. Every comment resource has its own URI (identifier) that points to it. The comment resource consists of an author and comment body, maybe some database ID and a time-stamp providing information about when the resource was last edited. We can add some metadata to this resource that provides information about the maximum acceptable length of a comment body…

Now we can view these resources in some representation. For example the list of the comment resources is stored in a database, but we won’t download the database file in its raw format, we will present an HTML page showing the comments, or we will return XML representation of the list, or JSON, or YAML, or some PDF. These are the representations. The server provides one or more representations of the resource for example HTML, JSON and XML. We can tell the server which representation we want to use. For example we can navigate with the browser to the URL http://forum-meddlings.rhcloud.com/comments and this will render the comment list in its HTML representation. If we navigate to http://forum-meddlings.rhcloud.com/comments.json, we will see the JSON representation of the list. Let’s use cURL:

  • curl -i http://forum-meddlings.rhcloud.com/comments
    

    This will retrieve the comment list in HTML format, the Content-Type response header value is ‘text/html;charset=utf-8’.

  • curl -i http://forum-meddlings.rhcloud.com/comments.json
    

    Now we see a JSON array containing the comments as JSON objects, the Content-Type response header value is ‘application/json;charset=utf-8’.

  • curl -i -H "Accept: application/json" \
    http://forum-meddlings.rhcloud.com/comments
    

    Again we see a JSON array containing the comments as JSON objects, the Content-Type response header value is ‘application/json;charset=utf-8’. We used the Accept request header to tell the server that we accept only JSON response.

The above conversations with the server are interesting. We want the server to Transfer to us the current State of the resource identified by the URL. We negotiate with the server for the REpresentation of the resource. This content negotiation is done by adding a format at the end of the URL or by setting the Accept request header. If the server doesn’t recognize the format it can send us HTTP 406 response (not acceptable).

We saw how we are able to view given resource state in a given representation, it is simple – we know where the resource is accessible via its URL and we request it from the server in given format via the request. But what if we want to create new resource or delete existing one or edit a resource.

The HTTP protocol has its methods (verbs). You all know about GET and POST, and maybe you know of PUT, DELETE, HEAD, TRACE and OPTIONS…

I’m going to introduce you to the REST CRUD (CREATE, READ, UPDATE, DELETE). We will use POST for creation, GET for reading, PUT for updating and DELETE for deleting resources. It is important to understand the difference between PUT and POST.
POST creates resources. It POSTs a new resource to a collection of resources; when you execute POST you don’t know what the URL of the new resource will be.
For example you have http://somewhere.com/resources and you POST a new resource to this URL, when the new resource is created it is given a new unique URL http://somwhere.com/resource/5. Now we can use PUT to update the resource located at this URL. PUT knows the URL of the resource it modifies.
So POST adds a new resource to a resource collection, creates resources, and PUT updates the resource data located at existing an URL.

Another thing about the HTTP verbs. GET, PUT and DELETE are idempotent. This means that if I execute the same PUT request one time or 100 times the result will be the same. Think about it… We modify the resource at http://somwhere.com/resource/5 setting the value ‘foo’ to ‘bar’, if we execute the same request 100 times the result we’ll be the same as the first time, a resource with attribute ‘foo’ set to ‘bar’. The same is true for DELETE – you can delete the resource one time or 100 times, in the end it will be deleted, the same as the first time. GET is reading, the same every time.
POST is another story if we POST the same resource data 5 times in the http://somewhere.com/resources collection we will have 5 different resources with the same data. Again the difference between POST and PUT, POST creates new resources with new IDS, new URLs…

I think we are ready to communicate with our RESTful API. We will create a new resource, then we will read it, we will update it and delete it. The API is simple:
– Here we have a collection of comment resources – http://forum-meddlings.rhcloud.com/comments
– Every comment resource has unique id and is located at http://forum-meddlings.rhcloud.com/comment/<id>
– When we read resources from the collection we can use their IDs to manipulate them.
– My application provides us we two representations – JSON and HTML, you can play with the HTML representation through your browser.
– Every comment has two mandatory fields – ‘author’ and comment ‘body’.

      1. Lets create a new comment; we will POST to http://forum-meddlings.rhcloud.com/comments a new comment represented as JSON data.
        We will tell the server how to parse this data by setting the request’s Content-Type header to ‘application/json’ and we will want the newly resource in JSON format, so the Accept header will be set to ‘application/json’ too:

        curl -i \
          -H "Accept: application/json" \
          -H "Content-Type: application/json" \
          -d '{"author": "meddle", "body": "My new comment!"}' \
          http://forum-meddlings.rhcloud.com/comments

        We created the new comment! Here is the response:

        HTTP/1.1 200 
        Date: Tue, 14 May 2013 13:27:56 GMT
        Server: Apache/2.2.15 (Red Hat)
        X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.17
        Content-Length: 69
        Status: 200
        Content-Type: application/json;charset=utf-8
        Vary: Accept-Encoding
        
        {"id":5,"author":"meddle","body":"My new comment!","time":1368538076}

        We can see that the id of the new comment is 5.

      2. Now its time to read the new comment using its id – its URL will be http://forum-meddlings.rhcloud.com/comment/5
        Request:
        curl -i \
          -H "Accept: application/json" \
          http://forum-meddlings.rhcloud.com/comment/5
        
        Response:
        HTTP/1.1 200 
        Date: Tue, 14 May 2013 13:30:43 GMT
        Server: Apache/2.2.15 (Red Hat)
        X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.17
        Content-Length: 69
        Status: 200
        Content-Type: application/json;charset=utf-8
        Vary: Accept-Encoding
        
        {"id":5,"author":"meddle","body":"My new comment!","time":1368538076}

        So we’ve created a new comment and we know its location, it is persisted there.

      3. Let’s edit our new comment:
        Request:
        curl -i \
          -H "Accept: application/json" \
          -H "Content-Type: application/json" \
          -d '{"author": "meddle", "body": "My new comment! Edited!"}' \
          -X PUT \
          http://forum-meddlings.rhcloud.com/comment/5
        Response:
        HTTP/1.1 200 
        Date: Tue, 14 May 2013 13:37:10 GMT
        Server: Apache/2.2.15 (Red Hat)
        X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.17
        Content-Length: 77
        Status: 200
        Content-Type: application/json;charset=utf-8
        Vary: Accept-Encoding
        
        {"id":5,"author":"meddle","body":"My new comment! Edited!","time":1368538630}
      4. Now after updating our comment why don’t we see the whole list:
        Request:
         curl -i \
          -H "Accept: application/json" \
          http://forum-meddlings.rhcloud.com/comments
        Response:
        HTTP/1.1 200
        Date: Tue, 14 May 2013 13:44:00 GMT
        Server: Apache/2.2.15 (Red Hat)
        X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.17
        Content-Length: 288
        Status: 200
        Content-Type: application/json;charset=utf-8
        Vary: Accept-Encoding
        
        [{"id":1,"author":"meddle","body":"First","time":1368526814},
        {"id":2,"author":"meddle","body":"This is from the JSON API!","time":1368526899},
        {"id":3,"author":"Some Gangsta","body":"Yo man!","time":1368530204},{"id":5,"author":"meddle","body":"My new comment! Edited!","time":1368538630}]
      5. Now we can delete our comment:
        Request:
        curl -i \
          -H "Accept: application/json" \
          -X DELETE 
          http://forum-meddlings.rhcloud.com/comment/5
        
        Response:
        HTTP/1.1 204 
        Date: Tue, 14 May 2013 13:48:22 GMT
        Server: Apache/2.2.15 (Red Hat)
        X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.17
        Status: 204
        Content-Length: 0
        Content-Type: text/plain
      6. So if try to read the deleted comment, we will receive HTTP 404 – Not Found:
        Request:
         curl -i \
          -H "Accept: application/json" \
          http://forum-meddlings.rhcloud.com/comment/5
        
        Response:
         HTTP/1.1 404
         Date: Tue, 14 May 2013 13:49:49 GMT
         Server: Apache/2.2.15 (Red Hat)
         X-Powered-By: Phusion Passenger (mod_rails/mod_rack) 3.0.17
         Content-Length: 30
         Status: 404
         Content-Type: application/json;charset=utf-8
        
        {"error":"Comment not found."}

This was one long post… But there is more : in the second part we will see the server implementation in Sinatra. Bye for now.