【问题标题】:Microservices UI Frontend with Java and ReactJS Server Side Rendering使用 Java 和 ReactJS 服务器端渲染的微服务 UI 前端
【发布时间】:2017-09-09 20:10:02
【问题描述】:

我目前的设计是让客户端使用浏览器连接到我的 (Java) Web API 网关,Web API 网关将调用每个 (Java) 微服务​​以获取其 JSON 数据并将其返回给发出请求的 UI 组件在客户端。

唯一的客户端渲染将来自每个 ReactJS UI 组件,用于对网关的重复请求。

在服务器端,完整的 HTML 视图将在发送回客户端之前呈现。

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)

这是不清楚的地方,最好让每个 UI 组件与 Web API 网关或它来自的父微服务通信以获取数据?

注意事项

  • 让 UI 组件与 Web API 网关通信似乎是合理的,但会将微服务耦合到网关,这意味着在微服务上公开新的 API,网关也需要更新。
  • 让 UI 组件直接与其微服务对话以获取数据,从而无需同时更新 Web API 网关,从而减少它们之间的耦合。但这会将微服务暴露给来自客户端浏览器的外部调用。

设计决策

  • 在 API 网关中拥有 UI 组件会创建一个 UI 单体,而不是让每个微服务负责自己的 UI 组件。使用单体方法简化了解决方案,并且还避免了在客户端请求特定视图时必须聚合每个微服务 UI 组件的复杂性。

工具:

  • Java
  • 纳舒恩
  • 空降向导
  • ReactJS
  • 分级
  • 网页包
  • NodeJS
  • NPM

如何使用 Java 和 ReactJS 在 Web API 网关上聚合多个微服务 ui 组件,然后将此预渲染的 HTML 数据与 JavaScript 应用程序一起提供给客户端?

有用的参考资料:

【问题讨论】:

  • 你从每个微服务加载数据为 json
  • @ConstantinGALBENU 是的,但我正在寻找有关如何执行该过程的指导。我已经更新了问题。
  • 使用服务器端渲染?
  • @ConstantinGALBENU 问题已更新。
  • 还是不明白要不要服务端渲染

标签: java reactjs microservices server-side-rendering


【解决方案1】:

问题

如何在 Web API 网关上的服务器端渲染期间聚合 ReactJS UI 组件。

解决方案

使用像Mustache 这样的模板框架来注入每个 ReactJS 组件服务器端的渲染 HTML 输出,然后将此 HTML 提供给客户端。

Github 仓库https://github.com/damorton/dropwizardheroku-webgateway

服务器端

我在 Web API 网关上实现的解决方案首先从微服务请求 JSON 数据,然后渲染 ReactJS 组件,同时将来自微服务的 JSON 数据注入为Props。一旦我将数据作为 HTML 字符串完全呈现的 ReactJS 组件,我使用 Mustache 模板将完全呈现的 ReactJS 组件 HTML 注入到 Mustache 模板中,然后将其返回给客户端。

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;
}

注意: Dropwizard 围绕 Mustache 模板执行了很多魔法,因此只需创建一个 index.mustache 文件并在构造 IndexView 类时引用它。将此View 返回给客户端会告诉 Dropwizard 呈现视图并返回 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>

客户端

在客户端,为了解决客户端和服务器端呈现的 HTML 不同的问题,由于最初安装组件时 ReactJS 组件的 props 不可用,当页面加载到时调用一个 javascript 函数从网关请求 JSON 数据。

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

当组件被挂载时,客户端的 HTML 不会重新渲染,React 会从服务器端呈现已经存在的 HTML,并且只会在每个组件挂载时添加事件监听器。这允许 React 单独更新其组件,并且还可以利用服务器端渲染。

【讨论】:

    【解决方案2】:

    所以,React component 需要两件事:JavaScript 源代码和数据。

    JavaScript 源代码可以由 CDN 提供。

    数据必须由微服务提供。

    如果您不想要服务器端渲染,那么骨架 index.html 文件以及 JS 文件由 CDN 提供。

    如果您需要服务器端渲染(例如,出于 SEO 目的),那么 API 网关(或其他 Web 服务器)将使用 NodeJS 渲染组件,方法是从 CDN 请求它们的源代码并从微服务请求它们的数据,然后将完整的HTML 返回到浏览器。

    在客户端,React 将使用API gateway 继续以JSON 的身份从正确的微服务加载其他数据。

    【讨论】:

    • 这是很棒的信息,帮助很大,但我使用的是 Java 而不是 NodeJS,我相信 ReactJS UI 组件应该只访问 Web API 网关而不是它来自的微服务。
    • @mortond 微服务使用 Java 还是 NodeJS 并不重要。您可以使用任何堆栈,组件不会在意。这个想法是组件 download 仅来自微服务的JSON 数据,使用或不使用API GatewayNodeJS 仅在需要服务器端渲染时使用。
    • 我知道如何实现微服务并不重要,但我使用的是 Java/Dropwizard。我的问题是关于使用 Java/ReactJS 堆栈的服务器端渲染。
    • 您的情况很复杂,因为您将组件的源代码保存在微服务中。您应该将它们全部保存在一个位置,即安装了NodeJS 的网络服务器,并将它们从该网络服务器呈现为Single page application
    • 你应该只使用Java来生成JSON动态内容
    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2015-03-01
    • 2017-05-16
    相关资源
    最近更新 更多