2012/09/17
17 Sep, 2012

Customizing WSO2 API Manager API Store and Publisher - Part 1

  • Lalaji Sureshika
  • - WSO2
Archived Content
This article is provided for historical perspective only, and may not reflect current conditions. Please refer to relevant product page for more up-to-date product information and resources.

Jaggery

Jaggery is a server side JavaScript framework to write web applications and HTTP focused Web services for all aspects of the application - front-end, communication, server-side logic and persistence - in pure JavaScript. It offers a completely JavaScript way to write all parts of Web applications and services as a way to reduce/eliminate mismatches across different layers of the Web application and API development experience. Closing the gap between web apps and web services, Jaggary enables you to create both applications and APIs at the same time. For more information visit the site https://jaggeryjs.org ,which contains more information,API documentation and samples.

This tutorial focuses on how to write a web application with Jaggery. As a real world use-case, we show the implementation of two web applications released with WSO2 API Manager [available with Beta1 version] known as API Store and API Publisher.

WSO2 API Manager

the WSO2 API Manager is a complete solution for publishing APIs, creating and managing a developer community and for scalable routing of API traffic. Basically it contains with three components called API Store, API Publisher and API Gateway. The API Store and API Publisher are web-applications developed to interact with third party users. Importantly those were built as JavaScript web applications by using Jaggery. For more information on WSO2 API Manager refer https://wso2.com/products/api-manager/

Getting Started

Pre-RequestiesWSO2 API Manager

Many real world web applications are as simple as the ones above. For a web application there are a large number of inter-connected UI pages written using HTML, CSS and JavaScript with JQuery or a similar library and the interaction with back-end is happening via form POST, JSON or XML data processing and data storing part done via SQL or a file type. As you can see every step of the process has significant impedance mismatches. This is where Jaggery comes to the spot as its capability of writing all parts of Web applications as a way to reduce/eliminate impedance mismatches across different layers of the Web application and API development experience.
If we pay attention on API Publisher and API-Store web applications,below is the general view of how we have implemented them with the help of jaggery.


Overview

Simply we can separate the story into three components.

1.Back-end Java Implementation [Data Access Layer]

All the API Manager apps related functionalities were written based on a java API as a Data Access Layer and some of the metadata had been stored to WSO2 Governance Registry while final storage kept as database storage.

2.Java Module implementation based on JavaScript Hostobjects[3]

As API-Manager related functionalities have been implemented based on a java API and not on a Web Service API,to invoke those back-end java implementations,there was a requirement to plug a java module to interact with both back-end layer[java] and front-end application[javascript]. That's how the two JavaScript hostobjects named as APIProviderHostObject and APIStoreHostObject were written and mapped the java logic in back-end to the JavaScript in front-end application.
How we have plugged these two hostobjects to the web-applications in API-Manager product is that,we have defined a module called 'apistore' from these two host objects from a module.xml file which you can found from {API Manager Home}/modules/apistore/module.xml and define two hostobjects inside that module.Sameway you can write your own java modules and plugged as above.

3.Front-end web-app implementation

Front-end web-applications has been written based on jaggery with using HTML,CSS and JavaScript and Jquery. For clarity and extensibility purposes,the web-applications have followed Model View Controller pattern. Below shown image is the folder structure of the api-store web app. Note that there's no specific directory structure to create a jaggery app,its upon to you based on the complexity of the app.

API-Store jaggery app directory structure

1) jaggery.conf -This file specifies the application specific configurations. It has used to define the URL-mappings for the pages, define welcome page,security-constraints,etc.In detail, the 'URL -mappings' section is really important to the jaggery app as when a request comes to the app, app will first try to find a mapped url from this section in jaggery.conf. If it matches, then that file will be invoked. Otherwise the *.jag file in the original url will be invoked.

2) site directory -This directory contains below important sub-directories;
  1. themes- The web-app has the capability of multiple-theme support and easily a user can add a new theme with less customized effort to the app. Currently API-Store app contains two themes called 'fancy' and 'modern'.Each theme contains;     

    • CSS -Contains the stying files of the application.

    • images-Contains the styling images of the application.

    • js-Contains the globally used JavaScript libraries related files as jquery,bootstrap

    • templates-Contains views of the web-application. The layout of a web page has been separated into layout blocks and each UI of such layout blocks has created using templates. A template can be considered as a re-usable UI block. Inside such a template the rendering HTML for the web UI part and related JavaScript event triggering have been included. Note that these templates can be reusable in any page,by including it to the required page. Each template should contain two files as; 

       -template.jag-Which contains the html code.Below is a sample template code.

      <% jagg.template( "api", function(inputs, outputs, jagg) { %>
      //The outputs displaying from the template and the inputs for the template can be via outputs and inputs parameters. 
      //All the htmls included here
       <% }); 
       %>

        -initializer.jag -Which uses to initialize the template by embedding JavaScript files or CSS to the template.Below is a sample initializer code. 

      <% jagg.initializer( "api ", {    preInitialize:function (data) {                
       //Below is how to import a JavaScript and CSS file to a template         
       jagg.addHeaderJS("template", "key", "jsFilePath"); 
      jagg.addHeaderCSS("template", "key", "CSSFilePath");  
       } }); %> 
        

      The layout which is predefined for a web page in API-Store is as below and the templates are set to the each sub layout parts according to the below layout.  


      The basic layout for a web page in API-Store is as above and it can be found with navigating to ‘templates/layout/base/template.jag’.  

      The basic web page template of the app can be found from templates/pages/base/remplate.jag.

      This base page contains the globaly common stylesheets and other related ui library references.

      From a template,you can include another template also by using following code.In current API-Store app you can find such a location from here.

      jagg.includeBlock("nameOfTemplae", inputParamsAsaJson);

       

  1. blocks -

    This directory can be considered as the Controller part of the web app. User actions on each View(template) are sent to the relevant block and then it handle the incoming HTTP requests.

    Each template has a corresponding block. Handling of incoming HTTP requests done from the jag files included inside directory called ‘ajax’ of each block.A block receives user requests and translates them to actions that the module directory should take from these jag files.Then with the response from module directory,the block selects the appropriate template [view] to pass the response as an input to the template.Below is a sample code of a block.

     

    <%
        jagg.block("api", {
           initializer:function (data) {
           //This initializer function is required when defining a block
           },
         getInputs:function () { //This method is optional,and it can be used to define input                                           //parameters for a block. 
        },
          getOutputs:function(inputs) { //Do some operations from the inputs of the block.  }
        });
        %>

  1. conf - This directory contains configurations related to web application User Interface. Inside the 'conf' directory,there's a file called site.conf which contains the settings for default theme,site context of the web application.

  1. pages- This directory contains the main pages that the web-application.This is the intial location comes after a browser request done by a user.

    In a page you can define its titile,what is the basic page and the layout referring from this page,what templates need to add into the page layout and inputs which has to pass into those templates as a json and page will render accordingly using render method of jagg.jag file. Below is a sample code block to render the page with defining its base page,tittle and templates for layouts.

jagg.render({"name":"page/base",
"inputs":{
"title":"API Store Listing",  //Page title
"pagePath":"/site/pages/list-apis.jag", //Page path
"body":[
{
"name":"layout/extended", //Page layout
"inputs":{   //Page inputs
"title":null,
 "middle":{
  "name":"api/listing", //template for the middle
   "inputs":{  //inputs for the template
    "apis":apis
        }
     }
    }
   }
  ]
}
});

3) modules directory 

This can be considered as the 'Model' of the application. It handles the state of the application.When a block invoke an action of a particular module from this directory,it will invoke the relevant function from JavaScript hostobject.

From jaggery server runtime,it'll process the requests which will go to JavaScript hostobjects.Then the server will return the response from backend as a mapped javascript object with Java response and pass the response again to block and then block will pass the response to corresponding template[view].

4) jagg directory

This is the most important directory of the API-Store web application as it contains the file jagg.jag ,which has kept for handling all functionalities to control and manage interactions among the modules,blocks and templates of the application. It contains custom methods develop for API Store/Publisher web applications to control its functionalities from Jaggery.Some of the important methods defined here is as below

  • jagg.render(obj) -To render the html content for a particular web-page of the application.
  • jagg.getThemePath() -To retrieve the theme defined in 'site/conf/site.json'.
  • jagg.getUserTheme() -To retrieve the user's theme defined in session.
  • jagg.getAbsoluteUrl(path) -To retrieve the absolute path of a relative url .
  • jagg.addHeaderJS(template, key, js) -To import a js file to a given template header .

References

[1] https://jaggeryjs.org

[2] https://wso2.com/products/api-manager/

[3]https://wso2.org/library/tutorials/writing-custom-hostobject

Author

Lalaji Sureshika, Software Engineer, WSO2 Inc

 

About Author

  • Lalaji Sureshika
  • Wso2