https://github.com/yuokada/quarkus-react-todo-app
https://github.com/yuokada/quarkus-react-todo-app
nodejs quarkus quarkus-example quarkus-quinoa
Last synced: about 2 months ago
JSON representation
- Host: GitHub
- URL: https://github.com/yuokada/quarkus-react-todo-app
- Owner: yuokada
- Created: 2024-02-26T17:58:26.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2025-02-20T01:00:13.000Z (over 1 year ago)
- Last Synced: 2025-02-20T02:21:43.147Z (over 1 year ago)
- Topics: nodejs, quarkus, quarkus-example, quarkus-quinoa
- Language: Java
- Homepage:
- Size: 831 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Codeowners: .github/CODEOWNERS
Awesome Lists containing this project
README
# Quarkus React Todo App
This project combines a Quarkus REST backend with a Vite/React Todo UI using the Quarkiverse Quinoa extension. Redis is used as a lightweight data store backing the Todo API.
## Architecture at a Glance
- **Backend**: Quarkus 3 + RESTEasy Reactive + Quarkus Redis Client. The Java code is organized into domain, application, infrastructure, and presentation packages under `src/main/java/io/github/yuokada/practice`.
- **Frontend**: React (Vite) with the main logic in `src/main/webui/src/App.jsx`.
- **Storage**: Redis (DevServices or `redis://localhost:6379/0`). Tasks are stored as the `TodoTask` record.
- **Quinoa**: Bridges Quarkus and the Vite app. In dev mode it proxies the Vite dev server; in prod it serves the built `dist/index.html` and assets.
## Package Structure
The backend now follows a simple Clean Architecture-style package split.
- `io.github.yuokada.practice.domain.model`
Holds business data types such as `TodoTask`, `Status`, and `Increment`. These classes do not depend on Quarkus or Redis APIs.
- `io.github.yuokada.practice.domain.repository`
Defines repository interfaces used by the application layer, such as `TodoRepository`, `TodoAsyncRepository`, and `IncrementRepository`.
- `io.github.yuokada.practice.application.service`
Contains use-case services like `TodoService`, `TodoAsyncService`, and `IncrementService`. These services depend on repository interfaces, not on Redis-specific implementations.
- `io.github.yuokada.practice.infrastructure.redis`
Contains Redis-backed implementations such as `RedisTodoRepository`, `RedisTodoAsyncRepository`, and `RedisIncrementRepository`. Quarkus Redis datasource access is isolated here.
- `io.github.yuokada.practice.infrastructure.dynamodb`
Contains DynamoDB-backed implementations such as `DynamoDbTodoRepository`, `DynamoDbTodoAsyncRepository`, `DynamoDbIncrementRepository`, and `DynamoDbClientProducer`. AWS SDK v2 access is isolated here.
- `io.github.yuokada.practice.presentation.rest`
Contains JAX-RS resource interfaces and implementations such as `TodoResourceImpl`, `TodoAsyncResourceImpl`, and `IncrementResource`. This layer maps HTTP requests and responses to application services.
Dependency direction:
- `presentation` -> `application` -> `domain`
- `infrastructure` -> `domain`
In practice, this means REST resources do not talk to Redis directly, and application services do not import Quarkus Redis APIs.
## Common Commands
| Purpose | Command | Notes |
| --- | --- | --- |
| Backend + frontend live coding | `./mvnw compile quarkus:dev` | Launches Quarkus dev mode and Quinoa-managed Vite dev server at `http://localhost:8080`. Dev UI at `/q/dev`. |
| Backend tests | `./mvnw test` | Uses Redis DevServices or local Redis depending on config. |
| Package JAR | `./mvnw package` | Artifacts end up in `target/quarkus-app/`. |
| Native build | `./mvnw package -Pnative` | Add `-Dquarkus.native.container-build=true` to build via container. |
| Start local Valkey | `docker compose up valkey -d` | Exposes Valkey on `localhost:6379` for local dev. |
| Start DynamoDB Local | `docker compose up dynamodb-local -d` | Exposes DynamoDB Local on `localhost:8000`. |
| Init DynamoDB tables | `./scripts/init-dynamodb.sh` | Creates `todo_tasks` and `app_counters` tables. Requires AWS CLI. |
| Frontend lint/check | `cd src/main/webui && npm run biome:check` | Runs Biome without modifying files. |
| Frontend dev only | `cd src/main/webui && npm run dev` | Runs Vite standalone (default port 5173). |
| Frontend build | `cd src/main/webui && npm run build` | Updates Quinoa’s source `dist/` folder. |
| Build container image (Jib) | `./mvnw package -Dquarkus.container-image.build=true` | Produces an OCI image via Jib; append `-Dquarkus.container-image.push=true` to push. |
Toolchain:
- Java: Temurin 25
- Node.js: 24.14.0
## Quinoa Configuration
`src/main/resources/application.properties` contains:
```properties
quarkus.quinoa.dev-server-port=5173
quarkus.quinoa.build-dir=dist
quarkus.quinoa.index-page=index.html
quarkus.quinoa.enable-spa-routing=true
```
This mimics the setup recommended in the [Advanced Guides](https://docs.quarkiverse.io/quarkus-quinoa/dev/advanced-guides.html). Dev mode proxies Vite, while prod serves the generated `dist/index.html` and falls back to it for SPA routing.
## REST API Summary
Base URL: `http://localhost:8080/api/todos`
| Method | Path | Description |
| --- | --- | --- |
| `GET /` | Fetch all tasks |
| `GET /{id}` | Fetch a single task |
| `POST /` | Create a task (`{"title":"...", "completed":false}`) |
| `PUT /{id}` | Update title/completed |
| `DELETE /{id}` | Delete a task (404 when missing) |
Additional async endpoints (`/api/async/todos`) and increment examples are exposed from the presentation layer. OpenAPI definitions are emitted into `openapi-definition/`.
see also: http://localhost:8080/q/swagger-ui/
## Frontend Highlights
- `App.jsx` implements list rendering, creation form, completion toggles, and deletion, all backed by fetch calls to `/api/todos`.
- `App.css` provides a lightweight card-style layout with responsive tweaks.
- Error/loading states feed back to the UI via status messages.
## Backend Selection
The backend storage can be switched at runtime via `app.repository.type` in `application.properties`.
| Value | Backend |
| --- | --- |
| `redis` | Valkey/Redis |
| `dynamodb` (default) | DynamoDB (or DynamoDB Local) |
To use DynamoDB Local in dev mode:
```properties
%dev.app.repository.type=dynamodb
%dev.app.dynamodb.endpoint-override=http://localhost:8000
```
Steps:
1. `docker compose up dynamodb-local -d`
2. `./scripts/init-dynamodb.sh`
3. `./mvnw compile quarkus:dev`
## Redis Usage
- **DevServices**: Leaving `%dev.quarkus.redis.hosts` commented lets Quarkus start Redis automatically in dev/test.
- **Local Redis**: Set `%dev.quarkus.redis.hosts=redis://localhost:6379/0` to reuse an existing instance.
- **Docker Compose**: `docker compose up -d` starts the local Valkey container defined in [`compose.yaml`](compose.yaml); stop it with `docker compose down`.
- Seed scripts (`users.redis`, `test-task.redis`) help bootstrap data when needed.
## Testing
- Tests live under `src/test/java/...` and rely on Quarkus JUnit5 + RestAssured.
- `%test.quarkus.redis.load-script=test-task.redis` loads fixtures for deterministic results.
## Container Image (Jib)
- The dependency `quarkus-container-image-jib` is included and configured via `application.properties`.
- Default image coordinates: `io.github.yuokada.practice/quarkus-react-todo-app:latest-jib`.
- Build locally: `./mvnw package -Dquarkus.container-image.build=true`
- Push to a registry: `./mvnw package -Dquarkus.container-image.build=true -Dquarkus.container-image.push=true`
- Override registry/name/tag as needed with `quarkus.container-image.*` properties or system properties (see [Quarkus container image guide](https://quarkus.io/guides/container-image)).
## Related Guides
- RESTEasy Reactive ([guide](https://quarkus.io/guides/resteasy-reactive)): Build reactive REST services with Quarkus.
- Quinoa ([guide](https://quarkiverse.github.io/quarkiverse-docs/quarkus-quinoa/dev/index.html)): Develop, build, and serve SPA frontends alongside Quarkus services.
- DynamoDB support plan: [`docs/dynamodb-support-plan.md`](docs/dynamodb-support-plan.md)
- Reactive return type notes: [`docs/reactive-return-types.md`](docs/reactive-return-types.md)
- Redis reactive tutorial: [`docs/redis-reactive-tutorial.md`](docs/redis-reactive-tutorial.md)
Live code the backend and frontend together with minimal configuration—Quinoa proxies the framework dev server during development and serves the generated assets in production.
## Provided Code
### Quinoa
This project uses Quinoa to wire a Vite/React frontend into the Quarkus application lifecycle.
[Related guide section...](https://quarkiverse.github.io/quarkiverse-docs/quarkus-quinoa/dev/index.html)
### React + Vite
- [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react/README.md) uses [Babel](https://babeljs.io/) for Fast Refresh
- [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react-swc) uses [SWC](https://swc.rs/) for Fast Refresh
### RESTEasy Reactive
Easily start your Reactive RESTful Web Services
[Related guide section...](https://quarkus.io/guides/getting-started-reactive#reactive-jax-rs-resources)
### Redis
- [Redis Extension Reference Guide - Quarkus](https://quarkus.io/guides/redis-reference)
- [Using the Redis Client - Quarkus](https://quarkus.io/guides/redis)
- [Dev Services for Redis - Quarkus](https://quarkus.io/guides/redis-dev-services)
- [valkey/valkey - Docker Image](https://hub.docker.com/r/valkey/valkey)
For more contributor-oriented details (naming, linting, etc.), see `AGENTS.md`.