Skip to main content

Consuming a REST service within JSF using JQuery and Handlebars [THE TRUE MVC APPROACH]

Posted by lamine_ba on July 29, 2012 at 3:13 PM PDT

The indispensable first step to getting the things you want out of life is this : decide what you want.
Ben Stein

INTRODUCTION

Ladies and Gentlemen, assuredly the chances for a technology to fall are huge if it is not driven by a real vision. And in my own perception, a technology is like a pattern, so without a constant transformation, it cannot live beyond the context in which it was made. And frankly, does one of you see any glory in taking a GUI pattern like MVC and apply it blindly on the web? For sure, if not done carefully, it would just lead to such question : "OK now, how are we going to make our web framework stateless?". But assuredly, if you are a clever developer, you should know that the solution of a problem does always lie in its cause. So is there any valuable reason to put yourselves into a turmoil?

Towards the Cloud

Have you the realization that the cloud is a distributed environment and that soon we will build in it an ecosystem of web applications that can communicate and collaborate through services to strengthen our Community? And to write this story, maybe we can consider to use a web framework like JSF to expose our data and our functionalities remotely via its awful and selfish programming model? Or to simply achieve that, shall we just give to JAX-RS the BIG respect it does deserve and make in the same time, JSF , a totally stateless web framework? But is it really a question I should ask to you or to those that have the TRUE mission to manage its future? But assuredly if they don't have the science and the skills to do so and to change the game, for sure Ladies and Gentlemen, soon we will do it for them.

Consuming a REST service using JQuery

Ladies and Gentlemen, assuredly the aim of this post is to show you, how to consume a RESTful web service within a JSF application. And for that, we will use today a JavaScript library like JQuery and a client-side templating system like Handlebars which itself is derived from another one called Mustache. And with your permission, I'm going now and from the perspective of a web developer to lay down things by first building the indispensable API in a total disconnection with any of its target clients.

Model

  1. @XmlAccessorType(XmlAccessType.NONE)
  2. @XmlRootElement
  3. class Customer {
  4.  
  5.   @XmlElement Long id
  6.   @XmlElement String firstName
  7.   @XmlElement String lastName
  8.  
  9. }

Controller

  1. @Path("/customers")
  2. class CustomerService {
  3.        
  4.         @GET
  5.         @Produces([MediaType.APPLICATION_JSON,MediaType.APPLICATION_XML])
  6.         def List<Customer> getCustomers() {
  7.             dao.customers
  8.         }
  9. }

And once it is done and from the perspective of a web designer who is working in a total disconnection with the web developers, I'm going now to design the Facelets page and to reference in it, the JavaScript libraries I will use to send an ajax request to my service and to render on the client-side the list of my Customers within a table.

View [index.xhtml]

  1. <!DOCTYPE html>
  2. <html  xmlns:h="http://java.sun.com/jsf/html">
  3.  
  4. <h:head>
  5.         <h:outputScript library="js" name="handlebars-1.0.0.beta.6.js"/>
  6.         <h:outputScript library="js" name="jquery.js"/>
  7.         <h:outputScript library="js" name="module.js"/>
  8. </h:head>
  9.                
  10. <body>
  11.  
  12.   <table>
  13.         <thead>
  14.            <tr>
  15.              <th>ID</th>
  16.              <th>First Name</th>
  17.              <th>Last Name</th>
  18.           </tr>
  19.         </thead>
  20.         <tbody>
  21.            <script id="template" type="text/x-handlebars-template">
  22.                  {{#each customer}}
  23.                    <tr>
  24.                      <td>{{id}}</td>
  25.                      <td>{{firstName}}</td>
  26.                      <td>{{lastName}}</td>
  27.                    </tr>
  28.                  {{/each}}
  29.           </script>
  30.         </tbody>
  31.  </table>
  32.  
  33. </body>
  34.        
  35.  </html>        
  36.              

JavaScript [module.js]

  1. var table={    
  2.        
  3.     display:function(url){
  4.         $.ajax({
  5.             type:"GET",
  6.             url:url,
  7.             dataType:"json",
  8.             success:function(data) {
  9.                 var template = $("#template").html();
  10.                 var render = Handlebars.compile(template);
  11.                 $("tbody").append(render(data));
  12.             }
  13.         });
  14.      }
  15.  
  16. };
  17.  
  18. $(function(){
  19.         table.display("/customers");
  20. });

Output

But don't ever think that the web designer is not intelligent enough to know that the next step for him, is to display the list of the Contacts of a Customer within a table. And that without a dedicated component suite for that, the only possibility he has, is to encapsulate this repetitive task within a reusable component by using the Composite Component Feature of JSF 2 which in turn will help him to resolve the REAL problem of hardcoding the url of the service within the JavaScript file. And this simple realization makes me think that JSF is not at all, the stupid web framework I thought it is.

Component [ table.xhtml ]

  1. <html xmlns:cc="http://java.sun.com/jsf/composite">
  2.  
  3. <cc:interface>
  4.         <cc:attribute name="url"/>    
  5. </cc:interface>
  6.  
  7. <cc:implementation>
  8.  
  9.         <table  url="#{cc.attrs.url}">
  10.             <script id="template" type="text/x-handlebars-template">
  11.                 <cc:insertChildren/>
  12.             </script>
  13.         </table>
  14.        
  15. </cc:implementation>
  16.  
  17. </html>

View [ index.xhtml ]

  1. <html   xmlns:h="http://java.sun.com/jsf/html"
  2.       xmlns:c="http://java.sun.com/jsf/composite/components">
  3.                
  4.         <body>
  5.  
  6.            <c:table url="/customers">
  7.                <thead>
  8.                   <tr>
  9.                       <th>ID</th>
  10.                       <th>First Name</th>
  11.                       <th>Last Name</th>
  12.                    </tr>
  13.                 </thead>
  14.                 <tbody>
  15.                     {{#each customer}}
  16.                       <tr>
  17.                         <td>{{id}}</td>
  18.                         <td>{{firstName}}</td>
  19.                         <td>{{lastName}}</td>
  20.                      </tr>
  21.                     {{/each}}
  22.                 </tbody>
  23.            </c:table>
  24.                
  25.         </body>
  26.        
  27.  </html>

MULTI-TEMPLATING SYSTEM [ METAMORFACES ]

A View does never stand alone, it is always connected to a Template via my Multi-Templating system [ Metamorfaces ]. And the next step is to have a cloud service deployed on a marvelous PAAS like CloudBees where a web designer can publish free and commercial templates so we can download or use them remotely. And if a web developer can do the same with a Module written with Groovy, Scala and such, Wooow! wouldn't the game just be more exciting?

  1. Carligian
  2. Cartion
  3. Archange
  4. Moanes
  5. Via Granitti
  6. Story of Glory
  7. Arlqueens
  8. Cimmanon
  9. Toodnen
  10. Platine45

100.Findario




twitter : lamine_ba

 

AttachmentSize
customers-api.png7 KB
module-directory.png4.19 KB
customers-render.PNG3.21 KB
module-directory-2.png5.13 KB