Microservices frontend with Java and ReactJS server side support

My current project is for clients to connect to my (Java) Web API Gateway using a browser, Web API Gateway will call each (Java) microservice to get their JSON data and return it to the UI component that made the request for client.

The only client-side rendering will be from each ReactJS UI component for repeated requests to the gateway.

On the server side, the complete HTML representation will be rendered before being sent back to the client.

Client browser

     ▼ (Request Dashboard View)

Web API Gateway

     ▼ (Request microservice JSON data)

Microservice A JSON Data
Microservice B JSON Data
Microservice C JSON Data
Microservice D JSON Data

     ▼ (Return JSON Data to gateway)

Web API Gateway

     ▼ (Render HTML and return to Client)

Client browser

     ▼ (ReactJS UI Components request data from API Gateway)

      

This is where it gets unclear, would it be better for each UI component to interact with the web API, or the parent Microservice it came from to get the data from?

Considerations

  • Having user interface components with the Gateway Web interface seems reasonable, but will bind the microservices to the gateway, which means that the gateway will also need to be updated to open the new API in the microservice.
  • Having UI components tied directly to the Microservice for data, eliminating the need to update the Web API gateway as well, keeping them less cohesive. But then it issues Microservice external calls from the client browser.

Design solutions

  • Having UI components in API gateways creates a UI monolith, not each microservice responsible for its own UI component. Taking a monolithic approach simplifies the solution and also avoids the complexities of bundling each component of the microservices UI when the client requests a specific view.

Instruments:

  • Java
  • Nashorn
  • Dropwizard
  • ReactJS
  • Gradle
  • Webpack
  • NodeJS
  • NPM

How can I aggregate multiple ui microservice components on a web API via Java and ReactJS and then serve that pre-rendered HTML data along with a JavaScript client application?

Useful links:

+3


source to share


2 answers


Problem

How to combine ReactJS UI components during server side rendering on the web API.

Decision

Use a templating framework like Mustache to insert rendered HTML output to each server side of the ReactJS components and then serve that HTML back to the client.

Github repo https://github.com/damorton/dropwizardheroku-webgateway

Server side

The solution I implemented on the web API gateway first requested the JSON data from the microservice and then rendered the ReactJS component by injecting the JSON data from the microservice as Props

. Once I had a fully rendered ReactJS component with data as an HTML string, I used the Mustache template to insert the fully rendered ReactJS HTML component into the Mustache template and then return it to the client.

WebGatewayResource.java

@GET
@Produces(MediaType.TEXT_HTML)
public IndexView index() throws IOException {

    // Get events json data from Events microservice
    ApiResponse events = getEventsJsonData();

    // Render the Events component and pass in props
    @SuppressWarnings("unchecked")
    List<Object> eventsProps = (List<Object>) events.getList();
    String eventsComponent = this.nashornController.renderReactJsComponent(kEventsUiComponentRenderServerFunction, eventsProps);

    IndexView index = new IndexView(eventsComponent);
    return index;
}

      



Note. Dropwizard does a lot of magic around Mustache templates, so all that was needed was to create a file index.mustache

and reference it when building the class IndexView

. Returning this View

to the client tells Dropwizard to render the view and return HTML.

index.mustache

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Dropwizard Heroku Event Service</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react-dom.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.5.4/react-dom-server.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.24.0/babel.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.16.1/axios.min.js"></script>
</head>
<body>
  <h1>Events</h1>
  <div id="events">{{{eventsComponent}}}</div>
  <script type="text/javascript" src="assets/js/bundle.js"></script>
  <script type="text/javascript" src="assets/js/client.js"></script>
</body>
</html>

      

Client side

On the client side, to fix the issue with the client and the HTML rendered side is different from the props for ReactJS components, which are not available when the component was originally installed, the javascript function is called when the page is loaded to request JSON data from the gateway.

client.js

var loadEventsFromServer = function(eventsUrl) {
    axios.get(eventsUrl).then(function(res) {
        var data = res.data.list;       
        renderClientEvents(data);
    });
};

loadEventsFromServer('https://domain.webapigateway.com/events');

      

ReactJS

The client-side HTML is not re-rendered when the component is compiled, React knows about the already existing HTML from server side rendering and only adds event listeners for each component when it is mounted. This allows React to update its components individually and also use server-side rendering.

+2


source


So a React component

requires two things: source code JavaScript

and data.

JavaScript source code can be provided by CDN.

The data must be provided to Microservices.



If you don't want server side rendering, the index.html skeleton file along with the files is JS

provided by the CDN.

If you require server side rendering (e.g. for SEO purposes) then the API gateway (or other web server) will render the components using NodeJS

, requesting their source code from the CDN and their data from the microservices, then return the full HTML

to the browser.

The client side React

will continue to load other data from the right microservice as JSON

using API gateway

.

+2


source







All Articles