In my previous tutorial I have explained about Spring Data REST + GemFire + jQuery Integration. This tutorial explains about the integration of Spring Data and Backbone.js integration. Backbone JavaScript framework isn’t like any of the previous frameworks when it comes to the integration.
Before getting started writing the integration application, let’s get the basics of the backbone framework. 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.
So, this tutorial walks you through the sample application for creating a backbone model that consumes the Spring Data REST and GemFire resources to use in the backbone view.
1. Project Structure
Here is the structure of the project that is used for this tutorial. It has only those files related to the Spring Data REST, GemFire and its repository.
2. Tools Used
- JDK 1.6.
- Tomcat 1.7.
- Maven 3.
- Spring Data REST.
- GemFire 7.0.1 Platform (JAR distribution).
3. Business Domain
We have a Message entity or object that needs to be used for the Restful service. This is the primary entity class for this tutorial.
Message.java
package net.javabeat.springdata.data; import org.springframework.data.annotation.Id; import org.springframework.data.annotation.PersistenceConstructor; import org.springframework.data.gemfire.mapping.Region; @Region("messages") public class Message { @Id private String messageId; private String message; public Message() { } @PersistenceConstructor public Message(String id, String message) { this.messageId = id; this.message = message; } public String getMessageId() { return messageId; } public void setMessageId(String messageId) { this.messageId = messageId; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } }4. Spring Data Repository
Repository provides you an abstraction layer in which you have never been providing an implementation for your CRUD operations even if it was a small portion of code. What you should have to do is to create your own interface that extends the Spring Data’s special Repository and the remaining work has been left for the Spring framework to complete the required implementation. So, you should have to provide a repository like below. If you look at the below class MessageRepository, it extends the CrudeRepository which is the spring data’s interface which defines the methods for the CRUD operations.
MessageRepository.java
package net.javabeat.springdata.repo; import net.javabeat.springdata.data.Message; import org.springframework.data.repository.CrudRepository; import org.springframework.data.rest.core.annotation.RepositoryRestResource; @RepositoryRestResource(collectionResourceRel="messages",path="messages") public interface MessageRepository extends CrudRepository<Message,Integer> {}As you’ve noted, the message repository is just an interface which is consider as an extension for the special spring data repository. You’ve mentioned the repository act on type i.e. Message business object in which the repository would play around of it to achieve the CRUD operations.
5. GemFire Spring Bean
It’s just a normal spring bean that used for providing a dummy messages that would be consumed by the services.
GemFireBean.java
package net.javabeat.springdata.bean; import net.javabeat.springdata.data.Message; import net.javabeat.springdata.repo.MessageRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class GemFireBean { MessageRepository messageRepository; public GemFireBean(){ } public MessageRepository getMessageRepository() { return messageRepository; } @Autowired public void setMessageRepository(MessageRepository messageRepository) { // Message repository has been set this.messageRepository = messageRepository; // Add some messages into GemFire for being seen Message message = new Message(); message.setMessageId("1"); message.setMessage("Hello JavaBeat !"); messageRepository.save(message); // Add message = new Message(); message.setMessageId("2"); message.setMessage("Hello GemFire REST"); messageRepository.save(message); System.out.println("Messages are filled"); } }6. Spring Bean Definition
This is the simple XML configuration for the spring beans.
SpringContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire" xmlns:gfe="http://www.springframework.org/schema/gemfire" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/data/gemfire http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd"> <!-- Search for spring components --> <context:component-scan base-package="net.javabeat"></context:component-scan> <!-- Declare GemFire Cache --> <gfe:cache/> <!-- Local region for being used by the Message --> <gfe:local-region id="messages" value-constraint="net.javabeat.springdata.data.Message"/> <!-- Search for GemFire repositories --> <gfe-data:repositories base-package="net.javabeat.springdata.repo"/> </beans>7. Repository Rest Dispatcher Servlet & Web deployment Descriptor
To install spring data rest alongside your existing web application, you need to include the appropriate configuration.
- Spring Data REST configuration is defined in a class called RepositoryRestMvcConfiguration.
- Since Spring Data REST is simply a spring MVC application, you only need to include the RepositoryRestDispatcherServlet to use the REST functionality when we use spring framework with XML configurations.
The web deployment descriptor seems like below.
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" metadata-complete="true" version="3.0"> <context-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring-config/SpringContext.xml</param-value> </context-param> <servlet> <servlet-name>rest</servlet-name> <servlet-class>org.springframework.data.rest.webmvc.RepositoryRestDispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>rest</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>8. Access GemFire Repositories
It’s just a steps for exposing the GemFire repositories through using of google Dev HTTP. For doing that just follow the below steps:
- From chrome browser open the Dev HTTP Client.
- Type your host followed by the port number followed with the web context for the deployed application which should results in the token http://localhost:8080/SpringData-GemFire-REST-1.0.
- For consuming the messages resources, you have to add the RepositoryRestDispactherServlet mapping url which mentioned in the web.xml and it’s /rest/ which results in url value like http://localhost:8080/SpringData-GemFire-REST-Bakbone.js-1.0./rest/
- Add the The path segment under which this resource is to be exported. that value was provided using the path property at the header of the MessageRepository in order to be able of exposing the messages resource like below.
As you’ve noted the messages resources prefixed with the rest word that mapped to the RepositoryRestDispatcherServlet.
9. Setup Environment – Create Bower Configuration Files
First, create a bower (bower is a package manager) control which tells the bower where to put the JavaScript dependencies and for doing that you have to follow the below steps.
- Download Git (is a free and open source distributed version control system DVCS) and install it into your machine. In case you have used a linux or other operating systems, try to install the desired version by visiting the Git site.
- Download the node.js platform ( is a software platform offers a safe way to build high performance and scalable network applications in JavaScript).
- After finish the installation of Git & node.js, next it will be using the command line, so open the command line and navigate through it into webapps within your own project. In our case the location is D:\Krishna\EclipseLink\Workspace\SpringData-GemFire-REST-Backbone.js\src\main\webapp.
- Type node -v to ensure that you are getting installed node.js successfully. You should find the version of the installed node.js platform. In our case the version is v0.10.28.
- Type npm -v to ensure that the npm (Node Package Manager) is installed properly. Node package manager used for managing the JavaScript dependencies, in which a JavaScript libraries have been installed, and a JavaScript programs have been published. In our case we’ve got 1.4.9 version.
- Type bower init for creating a bower.json file that describes each JavaScript package required by the project. Bower will ask for several bits of information such as project name, license, etc. If in doubt, just press Enter to accept the default.
- Next, use bower to install Backbone (since we’re using JavaScript modules, we’ll use the AMD version of Backbone), jQuery and Lodash (an alternative to Underscore), and an AMD module loader such as curl.js.
Where the resulted file should be bower.json that would carry the required information about JavaScript dependencies. And the project structure should be like
- From the command line type:
- bower install –save backbone-amd#~1
- bower install –save jquery#~2
- bower install –save lodash#~1
- bower install –save curl#~0.8
Bower will install these packages into directory.
And the bower.json file should look like
bower.json
{ "name": "SpringData-GemFire-REST-Backbone.js", "version": "0.0.1", "description": "Spring Data REST GemFire Backbone Integration", "main": "controller", "license": "MIT", "homepage": "index.html", "ignore": [ "**/.*", "node_modules", "bower_components", "test", "tests" ], "dependencies": { "backbone-amd": "~1", "jquery": "~2", "lodash": "~1", "curl": "~0.8" } }Now, you’re ready for getting started writing a backbone components.
10. Backbone Model
Backbone consumes data from a RESTful web services via models and collections. First, you’ll create a Backbone model that represents the data you want to consume from the REST service.
GemFireModel.js
define(function(require) { var Backbone = require('Backbone'); return Backbone.Model.extend({ urlRoot: 'http://localhost:8080/SpringData-GemFire-REST-Backbone.js-1.0/rest/messages', url: function() { return this.urlRoot; } }); });The model extends Backbone’s base Model, and sets the model’s urlRoot to the REST service at http://localhost:8080/SpringData-GemFire-REST-Backbone.js-1.0/rest/messages.
11. Backbone View
Next, you have to create a Backbone view to render the data in your GemFireModel.
GemFireView.js
define(function(require) { var Backbone = require('Backbone'); var $ = require('jquery'); var _ = require('underscore'); return Backbone.View.extend({ initialize: function() { console.log($('#gemfire-template').html()); this.template = _.template($('#gemfire-template').html()); this.listenTo(this.model, 'change', this.render); }, render: function(){ console.log(this.template); this.$el.html(this.template(this.model.attributes)); } }); })The view extends Backbone’s base View. The initialize method will be called when the view is instantiated. It uses Underscore to compile a template that will be used to render the model data, saving the compiled template in this.template.
Backbone automatically wraps the view’s root DOM Node (which will be provided when instantiating the view) in jQuery and makes it available as this.$el. The render method renders the compiled template, passing the model data, and then uses jQuery’s html() method to insert the rendered output into the DOM.
12. Backbone Controller
controller.js
define( function(require) { var GemFireModel = require('./GemFireModel'); var GemFireView = require('./GemFireView'); var $ = require('jquery'); var model = new GemFireModel(); model.fetch(); $(document).ready(function() { var gemfireView = new GemFireView({ el: $('.messages'), model: model }); }); });This controller instantiates a GemFireModel, and then invokes its fetch() method to fetch data from the REST service and populate the model’s data fields. Then it instantiates a GemFireView, passing the DOM Node where it should render, and the model. The view will automatically render the model using its compiled template.
13. Backbone Boot Script
This script configures the AMD loader: curl.config(). The main configuration property tells curl.js where to find the application’s main module, which will be fetched and evaluated automatically. The packages config object tells curl.js where to find modules in our application’s packages or in third-party packages.
boot.js
var curl; ( function () { curl({ main: 'controller', packages: { // Third-party packages curl: { location: 'bower_components/curl/src/curl' }, jquery: { location: 'bower_components/jquery/dist/jquery', main: '.' }, Backbone: { location: 'bower_components/backbone-amd/backbone', main: '.' }, underscore: { location: 'bower_components/lodash/lodash', main: '.' } } }); }());14. HTML View
Now that you have a model, view, and controller, you’ll create the HTML page that will load the client into the user’s web browser:
index.html
<!doctype html> <html> <head> <title>GemFire Backbone</title> <script data-curl-run="boot.js" src="bower_components/curl/src/curl.js"></script> <script type="text/html" id="gemfire-template"> <% _.each(_embedded.messages, function(message) { %> Message :: <%= message.message %> :: <a href='<%= message._links.self.href%>'>Message Link</a> <br/> <% }); %> </script> </head> <body> <h2>JavaBeat Tutorials</h2> <h3>Spring Data REST - GemFire - Backbone Integration</h3> <div class="messages"> </div> </body> </html>The script element will load curl.js and then load an application boot script named boot.js. The boot script will initialize and configure an AMD module environment and then start the client-side application code.
<script data-curl-run="boot.js" src="lib/curl/src/curl.js"></script>Next is the HTML template that your view uses to render the model data. Note that we use a script tag, with the type text/html. This tells the browser not to try to execute the script tag as JavaScript.
<script type="text/html" id="gemfire-template"> <% _.each(_embedded.messages, function(message) { %> Message :: <%= message.message %> :: <a href='<%= message._links.self.href%>'>Message Link</a> <br/> <% }); %> </script>Finally, there is the root DOM Node of the view. The view will render the model data, using the template, into this node:
<div class="messages"></div>15. Spring Data REST & Backbone Demo
The final project structure should look like
And once you’ve packaged the application using the maven and exporting it into Tomcat Apache for deploying. The execution should look like
16. Summary
This tutorial I have explained how to access the Spring Data REST services and GemFire in-memory repository through the Backbone components. Also this tutorial walks you through the various JavaScript techniques like Bower package manager, Underscore which are used as part of this tutorial. If you have any questions, please write it in the comments section.
Download Source Code
[wpdm_file id=109]