Quarkus is an exciting framework for building modern Java applications, and Quinoa takes it up a notch by streamlining Single Page Application (SPA) development. Together, they enable a seamless workflow for both frontend and backend developers. This guide walks through setting up a Quarkus-based SPA using React as an example, although the process works just as well for other frameworks.
Why Quinoa Matters
Quinoa elegantly integrates frontend development into Quarkus projects. Here’s why you should care:
- Unified Development:* Host your frontend and backend together during development.
- Automation:* Automatically build and serve your frontend as part of the Quarkus lifecycle.
- Streamlined APIs:* Simplify API calls with relative URLs.
Structuring Your Project
To keep things organized, place your frontend project as a submodule within the Quarkus project. Here’s a suggested structure:
Quarkus-Structure
|- src
| |- main
| |- docker
| |- resources
| |- webui (frontend project, must be named "webui")
Why Submodules?
- Separation of Concerns: Clear division between frontend and backend responsibilities.
- Independent Version Control: Manage the two projects separately.
Setting Up Quinoa in Quarkus
Step 1: Update Configuration
Add the following to application.properties
in the resources
directory:
quarkus.http.cors.origins=http://localhost
quarkus.http.cors=true
quarkus.quinoa.dev-server.port=3000
quarkus.quinoa.build-dir=dist
quarkus.quinoa.enable-spa-routing=true
Important Notes:*
quarkus.quinoa.build-dir
: Specifies the directory containing the built frontend files (e.g.,dist
for React), it should be the folder generated bynpm run build
.quarkus.http.cors
: Enables CORS for smoother API interactions during development.quarkus.quinoa.enable-spa-routing
: Fixes the SPA routing issue for Quarkus (see github issue for details)
Adjust build-dir
based on your frontend framework’s output directory.
Step 2: Add Dependency
In your pom.xml
, include:
<dependency>
<groupId>io.quarkiverse.quinoa</groupId>
<artifactId>quarkus-quinoa</artifactId>
<version>{latest-version}</version>
</dependency>
Developing with Quinoa
Seamless Integration
Once configured, running quarkus dev
or quarkus build
will:
- Detect your frontend project via its
package.json
. - Build and serve the frontend automatically.
Simplified API Calls
Use relative URLs (e.g., /api/1.0/create
) instead of absolute ones (e.g., http://localhost:8080/api/1.0/create
). Quinoa handles the routing, ensuring that requests reach the backend effortlessly.
Preparing for Production
Building Executables
- Create a Fat JAR:
bash quarkus build --no-tests
- Optional: Build a Native Executable:*
bash quarkus build --native --no-tests
Native executables eliminate the need for a Java runtime, offering faster startup and lower memory usage. But it usually takes some time for graalvm to support the latest version of java.
Multi-Platform Docker Images
To build a Docker image compatible with Linux and macOS:
- Enable
containerd
in Docker settings (How to). - Run the following command in the project root:
bash docker build --platform linux/amd64,linux/arm64 -f src/main/docker/Dockerfile.jvm -t quarkus/your-project:latest .
This image can run on diverse environments, including Apple Silicon.
Wrapping Up
Quarkus and Quinoa together redefine SPA development by combining frontend and backend workflows into a cohesive experience. With minimal setup, you can create, test, and deploy modern web applications efficiently. Whether you’re working on a personal project or deploying at scale, this combination simplifies your life.
For further exploration, dive into the official Quarkus documentation or the React and Quarkus guide.