WSO2 API Manager new look!

Kasun Thennakoon
8 min readFeb 6, 2019

--

About

This story is about developing new web applications for the next generation WSO2 API Manager product. These web apps are built using ReactJS framework as single page applications(SPAs). This story discusses the internals of the new web applications and solutions to some of the common issues you may come across when developing a SPA from scratch.

Overview

WSO2 API Manager(APIM) is a 100% open source API Management platform. The APIM product consists of four web-based UIs that allow users to interact with the APIM platform. Except for the carbon console web app which is a JSP based app, other three web apps (Store, Publisher and Admin Portal) are developed using the JaggeryJS language. JaggeryJS is also an open source language running on top of Rhino JavaScript engine.JaggeryJS has been used in other WSO2 products for about 8 years. It is primarily a server-side JS framework with the HTML templating capability. Additionally, it is also accessible to some java runtimes via OSGI.

The current version of the APIM UIs has server-side rendered apps. In the pure server-side rendered web apps, Each page you visit will be rendered from the server side and passed on to the browser as the whole web page. There is not much work that needs to be done on the browser in order to get the final view of the web page. In the current APIM JaggeryJS apps, We have used a hybrid approach wherein some pages we partially render the page from the back end, and fill the missing page element by rendering a template in the client side (HandlebarsJS). So there is a tight coupling between the Web App and the APIM Core Java APIs. Here is a good article on the topic `Rendering on the Web`. As stated in that article, The new API Manager UI apps have used the pattern `Client-Side Rendering (CSR)`

Client-Side Rendering (CSR), Taken from the article `Rendering on the Web`

The new APIM UI apps solve these limitations and drawbacks and give more flexibility for its users and developers. Even though the topic says ‘New Look!’, It is not just about the new look. It has been a complete re-write of all three web apps, changing the architecture and the underline technology stack. New APIM UI apps are developed as a Single Page Application(SPA). New APIM UI apps are developed as a Single Page Application (SPA) using React JS. The architectural change in the new APIM UI is that all the UI apps solely depending on the API Manager product REST APIs. This architectural change brings in a whole lot of new challenges. Following are some of them

  • Auth (Authentication & Authorization)
  • Page Navigations (Routing)
  • Internationalization (i18n) [3]
  • Theming
  • Managing UI Configurations
  • Accessibility [2]
  • Performance [4]
  • Extensibility
  • UI Testing [5]

… etc

Explaining how we overcame some of these topics will need to be discussed in separate articles. So, it’s not just a change in user experience, But a complete architectural revamp.

Application Architecture

The main architectural difference compared to the previous generation JaggeryJS app is, It is loosely coupled with the API Manager core via its REST APIs.There is no server-side rendering of ReactJS code at all. Complete React app is presented to the browser (We have code splitting in place, and it has been discussed later in this article), and from there it uses the API Manager REST API to fill out the missing information. The product REST APIs are fully compliant with OpenAPI 2.0(Swagger) specification. So it makes it easy to develop the UI applications using the REST APIs. This brings us a new challenge, which is Authorization and Authentication of the users. This was solved in a unique way, addressing some of the client side security issues as well. I will leave that topic for a new article & moving on. . .

File structure

First, We didn’t use Create React App for bootstrapping the applications. So the structure is a bit different than the usual. We have structured the ReactJS app into two parts. The Data and Service section and the React Components section. The main reason for this division is the separation of concerns.Data/Service section is dedicated for managing the Auth and receiving/submitting resource information via the REST API. To invoke the REST services with swagger definitions, we are using the SwaggerJS library. APIClient class is used for initializing the SwaggerJS library. and assigning the partial access token to the Authorization header stored in a cookie.

Noticed the `environment.label` code? That is because, we support managing multiple environments where API Manager is deployed, through a single instance of the UI app. In other words, You only need to run a single instance of Publisher, Store and Admin app for any number of APIM deployments. For example, If you have three deployments such as QA, Pre-Prod, and Prod, You only need one set of APIM UI applications to manage all those three deployments. Switching between environments is just a matter of selecting the environment from a drop-down. Here is a good article about the multi-environment feature in API Manager 3.

Taken from Renuka Fernando’s story

Next, the React Components. It only contains the presentational logic. Which means most of the files under the components directory are React component classes. There are mainly two types of React components, The container components, and presentation components. This pattern has been discussed in this article by Dan Abramov, Usage of this pattern can be seen in Publisher -> APIs -> Details Container component and the API Details overview page as a Presentation component.

Routing

Routing or the navigation through the pages are handled by React Router library. Path-based routing is preferred over hashed routing, because of the convenience of navigating through the app. To support the path based routing from the client side, we have configured the web server to serve the React app bundle for any request paths, except for the requests bound to static files(CSS, images etc). For example, if you navigate to /apis , /apis/{api_uuid}/overview or /endpoints/ etc... The web server is returning the app bundle with the complete SPA app. So it is the React Router library who renders the correct component of the app according to the current location(path) of the browser. Carbon-UI-Sever is been used as the web server for serving the SPA apps. (It is an in-house web server written using MSF4J). But you are free to use any other web servers like Nginx or Apache as long as you configure it to meet the above conditions.

Internationalization (i18n)

React-intl is used for internationalization, no magic here. It’s just using the library. It’s about using the FormattedMessage component in all the places where necessary.

Theming

The main challenge when providing the theming capability was to allow users to change the theme without building the whole application. This was achieved by using the Webpack Externals. The configuration JSON is loaded at the runtime. So just doing a page reload will reflect the changes in the theme file(unless it’s cached).

The APIM SPA apps are using Material UI as the UI element library. Hence the theming capability is inherited from the Material UI. We have added some extended parameters to default Material UI theming, such as rebranding capability through the theme file(i:e You can change the footer message, logo, page title etc through the theme file). These are special theme parameters that we have added to the theme file in order to give more customizability to the users.

Performance

At the beginning of the development, The performance was not an eye catching area. Apps were loading fast and the production bundle size was not more than few hundred kilobytes. The need to improve the performance came along with the development, when the size of the production bundle, Time to interactive, become noticeable.

To start with, We used the Webpack bundle analyzer to analyze the composition of the production app bundle.

Bundle analyzer was very helpful in identifying the unintended bundling of some dependencies. For example, due to some incorrect way of doing the imports in the material-ui library, The whole icon set was packed into the final bundle. Rectifying this along with some other minor fixes helped us to reduce the bundle size by ~50%.

Bundle analysis results on the current app

Even after the above changes, The production build size was still too large, about ~2MB (Gziped). Even though the Antd library contributes a lot to the bundle size, we couldn’t remove it from the dependencies list at that moment, because there were some left over Antd elements in some places of the app. (At the beginning, Antd UI elements were used in the SPA apps, but later we switched to Material-UI due to some limitations in the Antd library)

To further improve the app performance, we have used React-Loadable based code splitting. The login component was separated from the app. Since in most cases the login page is rendered as the first component. The component preloading is also in used to pre-fetch next the component(ProtectedApp) bundle while the user enters the username and password in the login page.

With the component base code splitting and preloading, we were able to gain a significant improvement(~60%) on page load. But still, there is a lot to do to improve the performance in all APIM SPA apps.

Try out — Demo

You can try out the new web apps from this demo setup of APIM 3.0.0-SNAPSHOT version. Login credentials are admin:admin.

API Manager — Developer Portal (Store) : Source

API Manager — Publisher : Source

API Manager — Admin Portal : Source

Feel free to open an issue in Product-APIM repository, If you find any flaws, bugs in the current implementation.

[1]: https://docs.wso2.com/display/AM300/Architecture

[2]: https://github.com/wso2/product-apim/issues/3935

[3]: https://github.com/wso2/product-apim/issues/1989

[4]: https://github.com/wso2/product-apim/issues/2063

[5]: https://github.com/wso2/product-apim/issues/3892

--

--