Quarkus for the Web

The basics

Serving static resources

假设您有一个 Quarkus 后端,并且您希望提供静态文件。这是最基本的情况,它在所有基于 Vert.x 的扩展中都得到开箱即用的支持,您必须将它们放置在应用程序的 META-INF/resources 目录中。

您可以在 HTTP reference guide 中找到更多信息。

Serving scripts, styles, and web libraries

但是,如果您想在您的网页中插入脚本、样式和库,您有 3 个选择:

  1. 从 cdnjs、unpkg、jsDelivr 等公共 CDN 消耗库,或将它们复制到您的 META-INF/resources 目录中。

  2. 使用运行时 Web 依赖项,例如 mvnpmWebJars,当将其添加到您的 pom.xml 或 build.gradle 时,它们可以直接 accessed from your web pages

  3. 使用绑定器将您的脚本(js、ts)、样式(css、scss)和 Web 依赖项打包在一起(参见 below)。

We recommend using a bundler for production 因为它提供了更好的控制、一致性、安全性和性能。好消息是,Quarkus 使用 Quarkus Web Bundler extension 使其变得非常容易和快速。

Bundling scripts, styles, and libraries

有两种捆绑 Web 资产的方法:

  1. 使用 the Quarkus Web Bundler extension,这是推荐的方式。无需任何配置,它就能立即组合所有内容,并遵循良好做法,例如消除无效代码、缩小、缓存等。

  2. 使用自定义捆绑器,例如 Webpack、Parcel、Rollup 等。这可以通过 Quarkus Quinoa extension轻松与 Quarkus 集成。

web bundle transition

Server-side rendering (SSR)

对于使用 Quarkus 的模板和服务器端渲染,有不同的引擎可用,例如 QuteFreemarker等。

Qute Web

Qute 专门设计来满足 Quarkus 需求,并帮助你处理模板、代码段和部分,以及渲染存储中的数据。它受到最著名的模板引擎的启发,它快速、类型安全、在本地工作,并具有许多不错的功能。

要安装 Qute Web,请按照 the instructions进行操作。

以下是一个简单的 Qute 模板示例:

src/main/resources/templates/pub/index.html
<!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 extension,此表达式将被捆绑的脚本和样式替换。
2 你可以在模板中直接使用 HTTP 参数。
3 此表达式已验证。尝试将表达式更改为 cdi:Product.notHere,构建将失败。
4 如果你安装了 Quarkus IDEs plugins,你将获得自动完成、实现链接和验证。

Model-View-Controller (MVC)

得益于 the Renarde extension,使用类似 Rails 的 Qute 框架,MVC 方法在 Quarkus 中也非常容易使用。

Web Bundler extension相关联,为满足你所有需求的构建现代 Web 应用程序打开了一条道路。以下是一个简单的 Renarde 控制器的外观:

src/main/java/rest/Todos.java
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();
    }
}

Single Page Applications

Quarkus 提供了非常可靠的工具,用于为 Quarkus(React、Angular、Vue、…)创建或集成单页应用程序,这里有 3 个选项:

  • Quarkus Quinoa为你与开发和生产兼容的 npm 兼容 Web 应用程序和 Quarkus 搭建桥梁。无需安装 Node.js 或配置你的框架,它会检测到它并使用合理的默认值。

  • Quarkus Web Bundler也是一种好方法,它更接近 Java 生态系统,并去除了大量的样板和配置,它快速且高效。有关此类 SPA 的示例,请参见 code.quarkus.iomvnpm.org

  • 使用 maven-frontend-plugin或类似工具实现自动化。

Full-stack microservices (Micro-frontends)

Quarkus 是全栈 Web 组件和全栈微服务(又称微型前端)的绝佳选择。通过使用 Web Bundler 或 Quinoa,你可以在很大程度上减少样板代码,并有效管理多个服务,而无需太多重复配置。

例如, quarkus.io上的 Quarkus documentation search engine使用 Web Bundler 创建全栈 Web 组件。利用 Lit Element 处理 Web 组件和 OpenSearch 处理索引,这是一种以动态方式增强静态网站体验的好方法。

更多关于此内容即将推出…

Other ways

我们已经描述了 Quarkus 最常见的创建 Web 应用程序的方法,但还有其他选择:

  • Vaadin Flow extension,对于这个独特的框架,它让你可以从 Java 代码直接构建 Web 应用程序,而不用编写 HTML 或 JavaScript。

  • JavaServer Faces (jsf) 是一项规范,用于在 Java 中构建基于组件的 Web 应用程序。该规范现已在 Quarkus 中可用, MyFaces扩展是 Quarkus 中 Faces 的一项实现。 PrimeFaces是一套 Faces 组件,而 OmniFaces,则是一个实用程序库。更多信息可在 this blog post找到。

  • 为你的首选 Web 框架创建 a new extension

Testing your web applications

对于测试 Web 应用程序来说, Quarkus Playwright非常易于使用。你可以创建有效的跨浏览器端到端测试,模仿用户交互并确保你的 Web 应用程序作为一个整体正常工作。最大的优势在于,它可以从所有 dev-service 和 Quarkus mocking 特性中受益。

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

Q&A

Why is Quarkus a very good option for Web Applications compared to other frameworks?

Quarkus 以其后端扩展生态系统和开发者体验而闻名,如果你将其与适用于前端的优秀扩展功能相结合,那将是完美的组合!现在,所有测试和开发模式特性都可以用于前端和后端。

What are the advantages of SSR (Server Side Rendering) over SPA (Single Page App)?

以下是在服务器上执行渲染工作的优势:

*Data Retrieval:*从服务器上抓取数据,靠近数据源。这可以通过减少检索渲染数据所需的时间和最小化客户端请求来提高性能。

*Enhanced Security:*敏感数据和逻辑的存储发生在服务器上,例如令牌和 API 密钥,不将它们暴露给客户端风险。

*Caching Efficiency:*服务器端渲染支持结果缓存,可以在用户和后续请求之间重复使用。这可以通过减少每次请求的渲染和数据抓取来优化性能并降低成本。

*Improved Initial Page Load and First Contentful Paint (FCP):*在服务器上生成 HTML 使得用户可以立即查看页面,无需等待客户端 JavaScript 下载、解析和执行才能进行渲染。

*Search Engine Optimization (SEO) and Social Media Shareability:*经过渲染的 HTML 有助于搜索引擎索引和社交网络预览,从而提高可发现性和可共享性。

I am hesitating between Quinoa and the Web Bundler, how should I make my decision?

你必须认为,使用这两个解决方案,捆绑输出的内容基本相同。另外,从一个解决方案切换到另一个解决方案并不是什么大问题,选择取决于开发人员体验以及找到最适合你的团队的解决方案。

一些指南:

Go for Quinoa:

  • 你的现有前端配置了一个兼容 npm 的构建工具,Quinoa 是最直接的选择。

  • 你的专用前端团队熟悉 NPM、Yarn 和其他用于构建单页面应用程序的工具。

  • 你想编写 Javascript 单元测试(例如 Jest、Jasmine,..),这在 Web Bundler 中是不可能的。但是,你可以在 NPM 上发布一个组件库,并从 Web Bundler 使用它。

  • 您在构建过程中使用非常具体的捆绑选项或特定工具

  • 您喜欢 package.json 和配置优化

Go for Web Bundler:

  • 对于简单的网络应用程序,Web Bundler 是最简单、最快的入门方法

  • 您更愿意靠近 Maven/Gradle 生态系统(不需要 Node.js),它为 Web 使用极其快速的捆绑器(esbuild)

  • 您希望减少样板代码和配置

How do I scale a Quarkus Web Application?

从现有的 Quarkus 后端提供几个静态页面和脚本并不是什么大开销,因此按照通常最简单的选项来扩展整个应用程序非常简单。您也可以将其分成两项服务:一项用于后端,一项用于前端。但是,在大多数情况下,与此种最初方法相比,此种方法不会产生实质性好处。

如果您的应用程序涉及大量静态资源,请考虑使用 CDN。Web Bundler 和 Quinoa 都可以配置为与 CDN 无缝配合工作,从而提高性能并改进资产分配。