微服务、API 网关和前端

Microservices, API Gateways, and Frontends

我最近开始探索微服务和 API 网关的概念,并且对如何托管前端端点感到特别困惑。

如果我有一个 API 网关充当所有服务请求之间的中间人,前端应该托管在哪里?如果我请求 /api/example,我知道我的 API 网关应该将其路由到适当的服务并转发该服务响应。但是,我不明白 API 网关应该如何在微服务上下文中处理 /home/ 。在这种情况下,我们希望将 /home/ 对应的 html/css/javascript 传递给发出 GET 请求的客户端。这是否意味着我们应该有某种前端服务?不会创建仅 returns HTML/CSS/JS 的服务是多余的并增加延迟,因为我们真正需要做的只是立即 return 与我们的 HTML/CSS/JS 关联前端?

我正在考虑的另一种方法是让 API 网关本身提供客户端呈现前端所需的 return HTML/CSS/JS 端点。换句话说,API 网关在接收到 /home/ 的 GET 请求时可以立即响应 /home/ 对应的 HTML 而不是调用服务。但是,我在网上看到 API 网关实际上不应该为端点提供服务,而只是将它们代理到服务。

这是我的主要问题:当您的后端使用微服务架构构建时,前端代码应该放在哪里?

对前端应用程序使用 API 响应,如果您return使用前端的整个主体,就没有意义,正如您指出的那样。

但是,您可以(最初)加载一个前端,其中包含比方说页眉、菜单、页脚和包含少量元素的主体部分,例如文章。

与此前端交互后,可以触发对 API 的操作(通常通过 JS Ajax 调用),这将从 API 请求新数据的特定部分, 一旦收到,JS 将只更新网页上的相关部分,而不会重新加载或替换(或刷新)整个页面。

如果操作得当,可以节省大量网络流量,从而使网站更加灵活,而无需在每次需要新数据进行可视化时完全重新加载。

一个简单的例子: 当您单击菜单中的 link 以加载联系表时,API 将 return 仅用于联系表的原始 HTML,或者它将 return(通常)一个 JSON object/array,将用于进一步 generate/replace 主体的一部分,现在成为联系表..

Where exactly should the frontend be hosted?

Where should frontend code go when your backend is built out using a microservice architecture?

您的前端(网络)应用程序通常位于 API 网关之前。对 HTML/CSS/JS 等资源的请求直接从前端应用程序本身提供服务,因此这里没有任何 API-网关参与。如果页面包含对后端(微)服务的 (AJAX) 调用,它可能(应该)通过 API 网关。从 托管 的角度来看,它们作为 单独的 网络应用程序托管。

how an API gateway should handle /home/ in a microservice context?

不会(即根本不会被 API 网关拦截)。像/home这样的请求是由前端应用程序本身直接服务的页面请求(当然,它会有自己的扩展机制,如集群、缓存等)

在回答您的问题之前,让我先了解一下不同的渲染策略:

传统服务器端渲染

现在很少见了。您不需要任何 API 网关,因为一切都在服务器中计算和呈现,您可以在那里执行对其他微服务的必要调用。

优点:简单;用户在页面加载时的即时交互;搜索引擎优化

缺点:每次都重新加载

客户端渲染

过去几年最受欢迎的选项。您提供一个基本的静态 HTML/CSS/JS 包,执行对 API 的请求以检索一些数据并使用某种模板引擎来呈现新页面和组件。

优点:无需完全重新加载;延迟加载;更丰富的互动;受益于 CDN

缺点:SEO;页面在加载时不交互;首次加载较慢

由于渲染发生在浏览器中,因此您不需要从服务器提供静态 HTML/CSS/JS 文件。相反,您应该使用 CDN 来更快地传送它们。

对非静态资源的其他请求将针对 API 网关执行,网关负责将请求转发给其他服务(或进行某种 orchestration/aggregation)。

现代服务器端渲染

由于像 Next.js 这样的框架,如今它越来越受欢迎。该页面最初在服务器中使用与在浏览器中使用的模板引擎相同的模板引擎呈现,因此您可以更快地发送交互式页面,同时保持客户端呈现的特性和优势。

在这种情况下,所有静态页面都可以通过 CDN 进行预渲染、缓存和服务。对于动态页面,您仍然可以发送部分 cached/rendered 页面,该页面稍后会从 API 网关获取额外的必要信息。

TL;DR:您不需要从 API 网关或服务器提供静态 HTML/CSS/JS。您应该通过 CDN 传送它们以缩短加载时间。

否则静态文件不应通过 API 网关提供,恕我直言。您可以让您的 /api/{resource} 请求通过它并将所有 /{page} 请求转发到静态资源。

我假设您的前端是单页应用程序。 SPA 具有 HTML、CSS、图像、字体等静态内容。它是部署为使用 REST APIs 从后端获取数据的静态网站的完美候选者。

在 AWS、GCP 等云环境中,建议将 SPA 应用程序与 REST APIs 分开托管。例如在 AWS SPA 中可以部署在 Amazon S3 中,并且无需通过 API 网关即可直接访问。

API 网关应该只用于路由 REST API 调用和执行横切关注点,例如身份验证等。但是这种方法的问题是您会在同时遇到 CORS 错误从前端点击 REST APIs,因为 SPA 和 API 网关将托管在不同的域中。要解决此问题,需要在 API 网关启用 CORS。

如果您正在寻找更简单的解决方案,可以通过 API 网关从服务提供前端。由于静态内容仅在 SPA 中提供一次,因此对于更简单的应用程序,从这种方法开始应该没问题。

https://aws.amazon.com/blogs/apn/how-to-integrate-rest-apis-with-single-page-apps-and-secure-them-using-auth0-part-1/

https://docs.aws.amazon.com/AmazonS3/latest/dev/WebsiteHosting.html

API 您已经提到的网关应该充当具有最少逻辑的 proxy/router。顾名思义,它的主要目的是为 different types of clients and address some of the non-functional aspects e.g. security. Provide high-level API [use case driven] based on requesting client[basically BFF/Backend for Frontend approach].

公开 API 而不是 GUI components/pages

当谈到让 frontend/GUI 适合微服务时,您可以考虑 UI Gateway/Container,它由 Micro FrontEnds. Also, refer to MF's site for details on micro frontends.

支持

因此,遵循前端的微服务架构,您的前端代码应该与其他微服务一起驻留在微前端中。