Backbone.js with Spring REST API - A Demo

Sudha Rajamanickam

Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface. Backbone.js is an Open source JavaScript library. Backbone.js was developed mainly for designing complex UI. Since it is separating data from the view it will be very easy for maintenance. OK, No more theory, Lets straightly dive into the demo.

Now, we going to have a UI like this,

User has to give his name and Date of birth. When he clicks the button, it has to hit the REST URL which is going to calculate his age and gives the result in the form of following JSON.
{
    "name": "John",
    "age": "22"
}
This data will be displayed in a table.And so the template is going to be something like, <tr><td>name</td><td>age</td></tr>. And lets go to the REST.  We are not going to focus much on Spring REST. Let me tell what are the jars you need to develop a REST and from where you have to download those jars. Content of the web.xml and mvc-dispatcher-servlet.xml files and the source code for our MVC controller and a POJO. 

1. Setting up the Project with a REST

We are not going to see deeply about writing aRSTsul web service, since the focus is on backbone. So, just copying and pasting the source files to your project will do. For Developing a simple REST you need the following jars.

spring-asm (3.0.5)
spring-beans (3.0.5)
spring-context (3.0.5)
spring-core (3.0.5)
spring-expression (3.0.5)
spring-web (3.0.5)
spring-webmvc (3.0.5)
commons-logging-1.1.1 
jackson-core-asl (1.9.10)
jackson-mapper-asl (1.9.10)
log4j-1.2.15

You can download the above jars from site http://mvnrepository.com/ search with above name and click the download link of the version given. Place them in classPath and Java 6 and Tomcat 7 required. Find the source of the web.xml and mvc-dispatcher-servlet.xml file. Just copy and paste them to your project’s WEB-INF folder

<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"
metadata-complete="true">

<display-name>Welcome to Tomcat</display-name>
<description>Welcome to Tomcat  </description>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

mvc-dispatcher-servlet.xml file. 

<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

<context:component-scanbase-package="mypack"/>

<mvc:annotation-driven/>
<mvc:default-servlet-handler/>

</beans>

We have to create a POJO say Person.java with name and age attributes and its getters and setters.

packagemypack;
publicclass Person {

String name;
String age;

public String getName() {returnname;}
publicvoidsetName(String name) {this.name = name;}
public String getAge() {returnage;}
publicvoidsetAge(String age)
{this.age = age;}

}

If you are using eclipse, your
Project explorer will look like,

 

Now the controller’s source code,

packagemypack;
importjava.util.Calendar;
importorg.springframework.stereotype.Controller;
importorg.springframework.web.bind.annotation.RequestMapping;
importorg.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/personService")
public class PersonDetailsController {
@RequestMapping("/getPersonDetails")
public @ResponseBody  Person getDetails(String name, String year, String month,String day){
Calendar calDOB = Calendar.getInstance();
calDOB.set(Integer.parseInt(year), Integer.parseInt(month), Integer.parseInt(day) );
Calendar calNow = Calendar.getInstance();
calNow.setTime(new java.util.Date());
intageYr = (calNow.get(Calendar.YEAR) - calDOB.get(Calendar.YEAR));
intageMo =
(calNow.get(Calendar.MONTH) - calDOB.get(Calendar.MONTH));
if (ageMo< 0)    
{
ageYr--;
}

Person person = new Person();
person.setName(name);
person.setAge(""+ageYr);
return person;

}
}

The root URL ‘/BackboneDemo’ is the name of out project. And the rest of the URL components are from @RequestMapping of the above controller.

http://localhost:8080/BackboneDemo/personService/getPersonDetails?name=John&year=1986&month=08&day=01

hit this URL in your browser. Preferred browser is chrome.  If you get response like below, you are now ready.

2. Looking into the Backbone side

Now we have arrived at the main part of this article. As you know Backbone.js is a MVC framework. It facilitates us to separate the interactive data (model ) from frontend(FE) rendering (view) logic.

Our FE contains a textbox for entering name and other text boxes for entering Date of birth details. And a button. If you click the button, it has to call a REST which will return some data based on your inputs and we have to render the data in the page. This is our FE logic
Let’s go into the implementation, As First step check out this HTML code.

 

demo.html

<!DOCTYPEhtml>
<html>
<head>

<title>Backbone Demo</title>
<script
src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js">
</script>
<script
src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.3.3/underscore-min.js">
</script>
<script
src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.9.2/backbone-min.js">
</script>
<scripttype="text/javascript"src="demo.js"></script>
</head>
<body>

       <scripttype="text/template"id="rowTemplate">
<tr><td><%=name%></td><td><%=age%></td></tr>
</script>

<divid="container1">
Name:<inputtype="text"id="name"><br/><br/><br/>
DOB Year:<inputtype="text"id="year"size="4">
Month:    <inputtype="text"id="month"size="2">
day:<inputtype="text"id="day"size="2">
<br/><br/>
<inputtype="button"value="Click"id="addMe">
<br/>  <br/><br/>    <br/>

              <tableid="myTable"border="6">
<tr>
<td>NAME</td>
<td>AGE</td>
</tr>
</table>
</div>

</body>
</html>

For this demo we are going to use following libraries in addition to Backbone.

1. jQuery (1.8.0)
2. Underrscore(1.3.3)

And the backbone version we are using is 0.9.2. Inside the backbone code we will use the utility functions of jQuery and underscore. Even backbone.js itself using these library. One more important thing to be noted is,  We have to maintain the above ‘script’ tag order. That is jQuery, underscore and then backbone.

Backbone introduced a new term called ‘template’. Check the above code you will find something like

<scripttype="text/template"id="rowTemplate">
<tr><td><%=name%></td><td><%=age%></td></tr>
</script>

As we already saw, The REST will give you a JSON with attributes ‘name’ and ‘age’. Using this dynamic data, we have to render them to the page. For this purpose, we have created a template with id ‘rowTemplate’. Using this id only we will refer it into our backbone code.
Next section in the demo.html is a div which will be referred as ‘container1’.  And all the UI elements inside this div are defined with an id. In backbone code, Using this id attributes we are going to collect the data entered by the user. Why we have wrapped all the UI elements inside the div (‘container1’) ?. will explain you that later.

Note the UI element with id ‘myTable’ . To this table only we are going to append the row(tr) formed with rowTemplate and dynamic data.
Backbone code comprises of two main sections.

      1.Model
      2.View

Creating a  Model:

As per the Backbones definition, “Models are the heart of any JavaScript application, containing the interactive data as well as a large part of the logic surrounding it: conversions, validations, computed properties, and access control.

 For creating a model we have to extend the Backbone class Backbone.Model.extendA backbone model is more or less similar to a Java class. It will have setters and getters also. After creating a Model we have to create an object for that Model. Then only it will be usable. For our application we are going to create a model called ‘Person’. Let’s check  how to create a Model for our project.

var Person = Backbone.Model.extend({
defaults : {
name :'Kalai',
age :'28'

},
initialize :function() {
alert("creating a Model");
},
urlRoot :"personService/getPersonDetails"

});

As you see, a Model basically contains three important sections. ‘defaults’ is used If you don’t want to have a REST. Initialize section is like a constructor in our java. That is, it will be called when you create a object for this Person model. And the final one is ‘urlRoot’. Its the url of our REST call. Since we are going to use REST we can skip defaults and initialize sections. We can create object as below,

var person = new Person();

Creating View

Creating a view also very similar to creating a model. We have to extend Backbone.View.extend. And then we have to create aobject . Lets straightly see the entire demo.js code. From that, will explain about the view.

demo.js

$(function() {
var Person = Backbone.Model.extend({
urlRoot : "personService/getPersonDetails"
});

var person = new Person();

varTableView = Backbone.View.extend({
el : "#container1",
template : _.template($("#rowTemplate").html()),
model : person,
initialize : function() {
this.model.on("change", this.render, this);
},
render : function() {

var template = this.template(this.model.attributes);
$("#myTable").append(template);
},
events : {
"click #addMe" : "addMe"
},

addMe : function(event) {
var self = this;

varparams = {
data : {
"name" : $("#name").val(),
"year" : $("#year").val(),
"month" : $("#month").val(),
"day" : $("#day").val()
}
}

var data = this.model.fetch(params);
}
});

vartableview = newTableView();
});

You noticed the el attribute? This is to inform the view to listen the events performed within that element. And also our view can see or refer the elements within that element. So, our view can listen the actions performed within the ‘container1’.

_.template() is a undelscore’s fuction which will load ‘rowTemplate’ into the view.’model’  attribute will have the object of our model ‘Person’. The code inside the initialize will tell the view to call ‘render’ function when a change happens to the model.  And then the render function will pass the attributes ’name’ and ‘age’ to the ‘rowTemplate’.

"click #addMe" : "addMe"

Means, when click action performed on the element with id ‘addMe’, view has to call addMe function. Inside the addMe function, the date entered in the UI are collected. And finally the fetch() call will do a GET request to the REST call.

Now hit the urlhttp://localhost:8080/BackboneDemo/demo.html

About Author

Author Sudha Rajamanickam  working in company Banca sella (Chennai branch) for three and half years. For more information you can reach her at sudha.rajamanickam.a@gmail.com








}