Quarkus Web 开发
Quarkus 提供了多个扩展来创建 Web 应用程序,本文档旨在为不同的使用场景提供扩展使用方向。
1. 基础知识
1.1. 提供静态资源
假设你有一个 Quarkus 后端,并且你想提供静态文件。这是最基本的情况,我们所有基于 Vert.x 的扩展都支持开箱即用,你必须将它们放在应用程序的 META-INF/resources
目录中。
你可以在 HTTP 参考指南中找到更多信息。
1.2. 提供脚本、样式和 Web 库
但是,如果你想在你的网页中插入脚本、样式和库,你有 3 个选项
我们建议在生产中使用捆绑器,因为它提供更好的控制、一致性、安全性和性能。好消息是 Quarkus 通过 Quarkus Web Bundler 扩展使其变得非常容易和快速。 |
1.3. 捆绑脚本、样式和库
有两种方法可以捆绑你的 Web 资源
-
使用 Quarkus Web Bundler 扩展,这是推荐的方式。无需任何配置,它可以在瞬间将所有内容放在一起,并遵循良好的实践,例如死代码消除、最小化、缓存等。
-
使用自定义捆绑器,例如 Webpack、Parcel、Rollup 等。这可以使用 Quarkus Quinoa 扩展轻松地与 Quarkus 集成。

2. 服务器端渲染 (SSR)
对于 Quarkus 的模板和服务器端渲染,有不同的引擎可用,例如 Qute 或 Freemarker 以及其他。
2.1. Qute Web
Qute 专门设计用于满足 Quarkus 的需求,并帮助你处理模板、代码片段和局部,并呈现来自你存储的数据。它受到最著名的模板引擎的启发,它速度快、类型安全、可在 Native 模式下工作,并且有很多不错的功能。
要安装 Qute Web,请按照说明进行操作。
这是一个简单的 Qute 模板示例
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Qute Page</title>
{#bundle /} (1)
</head>
<body>
<h1>Hello {http:param('name', 'Quarkus')}</h1> (2)
<ul>
{#for item in cdi:Product.items} (3)
<li>{item.name} {#if item.active}{item.price}{/if}</li> (4)
{/for}
</ul>
</body>
</html>
1 | 使用 Web Bundler 扩展,此表达式将被捆绑的脚本和样式替换。 |
2 | 你可以直接在模板中使用 HTTP 参数。 |
3 | 这个表达式已经过验证。尝试将表达式更改为 cdi:Product.notHere ,构建将会失败。 |
4 | 如果你安装了 Quarkus IDE 插件,你将拥有自动完成、链接到实现和验证。 |
2.2. 模型-视图-控制器 (MVC)
借助 Renarde 扩展(一个使用 Qute 的类似 Rails 的框架),MVC 方法在 Quarkus 中也变得非常容易。
与 Web Bundler 扩展相关联,这条路已经为满足你的所有需求的现代 Web 应用程序敞开了大门。这是一个简单的 Renarde 控制器的样子
package rest;
[...]
public class Todos extends Controller {
@CheckedTemplate
static class Templates {
public static native TemplateInstance index(List<Todo> todos);
}
public TemplateInstance index() {
// list every todo
List<Todo> todos = Todo.listAll();
// render the index template
return Templates.index(todos);
}
@POST
public void add(@NotBlank @RestForm String task) {
// check if there are validation issues
if(validationFailed()) {
// go back to the index page
index();
}
// create a new Todo
Todo todo = new Todo();
todo.task = task;
todo.persist();
// send loving message
flash("message", "Task added");
// redirect to index page
index();
}
@POST
public void delete(@RestPath Long id) {
// find the Todo
Todo todo = Todo.findById(id);
notFoundIfNull(todo);
// delete it
todo.delete();
// send loving message
flash("message", "Task deleted");
// redirect to index page
index();
}
@POST
public void done(@RestPath Long id) {
// find the Todo
Todo todo = Todo.findById(id);
notFoundIfNull(todo);
// switch its done state
todo.done = !todo.done;
if(todo.done)
todo.doneDate = new Date();
// send loving message
flash("message", "Task updated");
// redirect to index page
index();
}
}
查看 Quarkus Insights Episode #178。第一部分是使用 Renarde 创建 CMS 的动手演示。你也可以使用 web-lab repo来尝试一下)。 |
3. 单页应用程序
Quarkus 提供了非常可靠的工具来创建或集成单页应用程序到 Quarkus (React, Angular, Vue, …),这里有 3 个选项
-
Quarkus Quinoa 将你的 npm 兼容 Web 应用程序和 Quarkus 连接起来,用于开发和生产。无需安装 Node.js 或配置你的框架,它将检测到它并使用合理的默认值。
-
Quarkus Web Bundler 也是一个好方法,它更接近 Java 生态系统,并删除了大量样板代码和配置,它快速而高效。有关此类 SPA 的示例,请参见 code.quarkus.io 和 mvnpm.org。
-
使用 maven-frontend-plugin 或类似工具进行自动化。
4. 全栈微服务(微前端)
Quarkus 是全栈 Web 组件和全栈微服务(又名微前端)的绝佳选择。通过利用 Web Bundler 或 Quinoa,你可以显着减少样板代码,并在没有太多配置重复的情况下有效地管理多个服务。
例如,quarkus.io 上的 Quarkus 文档搜索引擎 使用 Web Bundler 创建全栈 Web 组件。使用 Lit Element 作为 Web 组件,OpenSearch 用于索引,这是一种以动态方式增强静态网站体验的好方法。
更多关于此的内容即将推出……
5. 其他方式
我们描述了 Quarkus 创建 Web 应用程序的最常见方法,但还有其他选择
-
Vaadin Flow extension,适用于这个独特的框架,允许你直接从 Java 代码构建 Web 应用程序,而无需编写 HTML 或 JavaScript。
-
JavaServer Faces (jsf) 是在 Java 中构建基于组件的 Web 应用程序的规范。它在 Quarkus 中可用,MyFaces 扩展是 Quarkus 的 Faces 实现。PrimeFaces 是 Faces 组件套件,OmniFaces 是一个实用程序库。更多信息请参阅这篇博文。
-
为喜爱的 Web 框架创建新扩展。
6. 测试你的 Web 应用程序
对于测试 Web 应用程序,Quarkus Playwright 非常容易使用。你可以创建有效的跨浏览器端到端测试,模拟用户交互并确保你的 Web 应用程序作为一个整体正常运行。最大的优点是它可以从所有 dev-services 和 Quarkus 模拟功能中受益。
@QuarkusTest
@WithPlaywright
public class WebApplicationTest {
@InjectPlaywright
BrowserContext context;
@TestHTTPResource("/")
URL index;
@Test
public void testIndex() {
final Page page = context.newPage();
Response response = page.navigate(index.toString());
Assertions.assertEquals("OK", response.statusText());
page.waitForLoadState();
String title = page.title();
Assertions.assertEquals("My Awesome App", title);
// Make sure the web app is loaded and hits the backend
final ElementHandle quinoaEl = page.waitForSelector(".toast-body.received");
String greeting = quinoaEl.innerText();
Assertions.assertEquals("Hello from REST", greeting);
}
}
7. 问答
7.1. 与其他框架相比,为什么 Quarkus 是 Web 应用程序的一个非常好的选择?
Quarkus 以其后端扩展生态系统和开发者体验而闻名,如果你将其与前端的强大扩展结合起来,那么它就是一个完美的组合!所有的测试和开发模式功能现在都可用于前端和后端。
7.2. 与 SPA(单页应用程序)相比,SSR(服务器端渲染)的优势是什么?
以下是在服务器上执行渲染工作的好处
数据检索:在服务器上,更接近数据源的地方获取数据。这通过减少检索渲染所需数据的时间并最大限度地减少客户端请求来提高性能。
增强的安全性:敏感数据和逻辑的存储发生在服务器上,例如令牌和 API 密钥,而不会将它们暴露给客户端风险。
缓存效率:服务器端渲染允许结果缓存,可以在用户和后续请求之间重复使用。这通过减少每次请求的渲染和数据获取来优化性能并降低成本。
改进的初始页面加载和首次内容绘制 (FCP):在服务器上生成 HTML 使户能够立即查看页面,无需等待客户端 JavaScript 下载、解析和执行以进行渲染。
搜索引擎优化 (SEO) 和社交媒体可分享性:渲染的 HTML 有助于搜索引擎索引和社交网络预览,从而提高可发现性和可分享性。
7.3. 我在 Quinoa 和 Web Bundler 之间犹豫不决,我应该如何做出决定?
你必须考虑到这两种解决方案的捆绑输出本质上是相同的。此外,从一个切换到另一个并不是什么大问题,选择在于开发者体验和找到最适合你的团队的方案。
一些指导原则
选择 Quinoa
-
你有一个使用 npm 兼容构建工具配置的现有前端,Quinoa 是最直接的选择。
-
你有一个专门的前端团队,他们熟悉诸如 NPM、Yarn 之类的工具和其他用于构建单页应用程序的工具。
-
你想编写 Javascript 单元测试(例如 Jest、Jasmine 等),这在 Web Bundler 中是不可能的。但是,你可以在 NPM 上发布组件库并从 Web Bundler 中使用它。
-
你在构建过程中使用非常具体的捆绑选项或特定工具
-
你喜欢 package.json 和配置调整
选择 Web Bundler
-
对于简单的 Web 应用程序,Web Bundler 是入门的最简单、最快的方法
-
你更喜欢保持靠近 Maven/Gradle 生态系统(不需要 Node.js),它使用一个非常快速的 Web 捆绑器 (esbuild)
-
你想减少样板代码和配置