quarkus

Applies to: Quarkus 3.x, Java 17+, Cloud-Native Microservices, GraalVM Native, Kubernetes

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "quarkus" with this command: npx skills add ar4mirez/samuel/ar4mirez-samuel-quarkus

Quarkus Guide

Applies to: Quarkus 3.x, Java 17+, Cloud-Native Microservices, GraalVM Native, Kubernetes

Core Principles

  • Kubernetes-Native: Designed for containers, fast startup, low memory footprint

  • Developer Joy: Live reload via Dev Services, Dev UI, continuous testing

  • Unified Reactive/Imperative: Choose per-endpoint, both coexist in one app

  • Build-Time Optimization: Extensions process metadata at build time, not runtime

  • GraalVM First-Class: Native compilation with millisecond startup and minimal RSS

  • Standards-Based: MicroProfile, Jakarta EE, Vert.x, SmallRye under the hood

Guardrails

Project & Dependencies

  • Use Quarkus BOM for version management (never pin individual Quarkus artifact versions)

  • Add extensions via ./mvnw quarkus:add-extension rather than editing pom.xml manually

  • Run ./mvnw quarkus:dev for live reload; never restart manually during development

  • Use Dev Services (auto-provisioned containers) for databases, Kafka, Redis in dev/test

  • Keep application.properties profile-aware: %dev. , %test. , %prod. prefixes

CDI (Contexts and Dependency Injection)

  • Use @ApplicationScoped for stateless services (one instance per app)

  • Use @RequestScoped only when you need per-request state

  • Prefer constructor injection or @Inject fields (constructor preferred for testability)

  • Avoid @Dependent scope unless you need a new instance per injection point

  • Use @Startup for beans that must initialize eagerly at boot

  • Register beans for native with @RegisterForReflection only when reflection is required

  • Produce CDI beans via @Produces methods for third-party objects

RESTEasy Reactive Resources

  • Use RESTEasy Reactive (quarkus-resteasy-reactive ), not classic RESTEasy

  • Return Uni<T> or Multi<T> for non-blocking I/O; plain types for blocking is acceptable

  • Keep resource classes thin: validate input, delegate to service, map response

  • Use @Valid on request parameters for Bean Validation

  • Annotate with @Produces(APPLICATION_JSON) and @Consumes(APPLICATION_JSON)

  • Use @Path versioning: /api/v1/resource

  • Add OpenAPI annotations (@Operation , @APIResponse ) on every endpoint

  • Secure endpoints with @RolesAllowed , @Authenticated , or @PermitAll

Panache ORM

  • Active Record (extends PanacheEntity ): good for simple CRUD entities

  • Repository (implements PanacheRepository<T> ): good for complex queries, better testability

  • Use Uni<T> return types with hibernate-reactive-panache for non-blocking DB access

  • Add custom finder methods on entity or repository (e.g., findByEmail )

  • Use @WithTransaction on service methods that write, not on resources

  • Set quarkus.hibernate-orm.database.generation=validate and manage schema via Flyway

  • Always provide @PrePersist / @PreUpdate for audit timestamps

Configuration

  • Use application.properties with profile prefixes: %dev. , %test. , %prod.

  • Inject config values with @ConfigProperty(name = "key", defaultValue = "fallback")

  • Group related config with @ConfigMapping interfaces

  • Never hardcode secrets; use ${ENV_VAR:default} placeholder syntax

  • Enable Dev Services for local containers: quarkus.devservices.enabled=true

Error Handling

  • Create domain exceptions: ResourceNotFoundException , DuplicateResourceException

  • Register JAX-RS @Provider classes implementing ExceptionMapper<T>

  • Return structured error bodies: { title, status, detail, timestamp }

  • Map ConstraintViolationException to 400 with per-field error details

  • Log at WARN for client errors, ERROR for unexpected failures

Native Build Compatibility

  • Avoid runtime reflection (use @RegisterForReflection when unavoidable)

  • Avoid dynamic proxies and runtime bytecode generation

  • Test native build regularly: ./mvnw verify -Pnative

  • Use @BuildStep extensions for build-time processing

  • Prefer compile-time DI and annotation processors (MapStruct, Panache)

  • Use quarkus.native.container-build=true to build without local GraalVM

Project Structure

myproject/ ├── src/main/java/com/example/ │ ├── resource/ # JAX-RS endpoints (thin controllers) │ │ ├── UserResource.java │ │ └── AuthResource.java │ ├── service/ # Business logic │ │ └── UserService.java │ ├── repository/ # Panache repositories (optional if using active record) │ │ └── UserRepository.java │ ├── entity/ # JPA entities with Panache │ │ └── User.java │ ├── dto/ # Request/response records │ │ ├── UserRequest.java │ │ └── UserResponse.java │ ├── mapper/ # MapStruct mappers (compile-time, CDI-scoped) │ │ └── UserMapper.java │ ├── exception/ # Domain exceptions + ExceptionMappers │ │ ├── ResourceNotFoundException.java │ │ ├── DuplicateResourceException.java │ │ └── ExceptionMappers.java │ └── health/ # MicroProfile Health checks │ └── DatabaseHealthCheck.java ├── src/main/resources/ │ ├── application.properties # Config with profile prefixes │ └── db/migration/ # Flyway SQL migrations │ └── V1__create_users.sql ├── src/main/docker/ │ ├── Dockerfile.jvm │ └── Dockerfile.native ├── src/test/java/com/example/ │ ├── resource/ # @QuarkusTest integration tests │ │ └── UserResourceTest.java │ └── service/ # Unit tests with @InjectMock │ └── UserServiceTest.java └── pom.xml

  • resource/ -- Thin REST endpoints; input validation and response mapping only

  • service/ -- All business logic; transactional boundaries live here

  • repository/ -- Data access (skip if active record pattern suffices)

  • entity/ -- JPA entities; keep domain logic minimal, push to service

  • dto/ -- Java records for request/response; use Bean Validation annotations

  • mapper/ -- MapStruct interfaces with componentModel = "cdi"

  • exception/ -- Domain exceptions and JAX-RS ExceptionMapper providers

  • health/ -- MicroProfile HealthCheck implementations

CDI Pattern

@ApplicationScoped public class UserService {

@Inject
UserRepository userRepository;

@Inject
UserMapper userMapper;

@WithTransaction
public Uni&#x3C;UserResponse> createUser(UserRequest request) {
    return userRepository.existsByEmail(request.email())
        .flatMap(exists -> {
            if (exists) {
                return Uni.createFrom().failure(
                    new DuplicateResourceException("User", "email", request.email()));
            }
            User user = userMapper.toEntity(request);
            return userRepository.persist(user).map(userMapper::toResponse);
        });
}

public Uni&#x3C;UserResponse> getUserById(Long id) {
    return userRepository.findById(id)
        .onItem().ifNull().failWith(
            () -> new ResourceNotFoundException("User", "id", id))
        .map(userMapper::toResponse);
}

}

RESTEasy Resource Pattern

@Path("/api/v1/users") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Tag(name = "Users", description = "User management APIs") public class UserResource {

@Inject
UserService userService;

@POST
@Operation(summary = "Create a new user")
@APIResponse(responseCode = "201", description = "User created")
public Uni&#x3C;Response> createUser(@Valid UserRequest request) {
    return userService.createUser(request)
        .map(user -> Response
            .created(URI.create("/api/v1/users/" + user.id()))
            .entity(user).build());
}

@GET
@Path("/{id}")
@RolesAllowed({"USER", "ADMIN"})
@SecurityRequirement(name = "jwt")
@Operation(summary = "Get user by ID")
public Uni&#x3C;UserResponse> getUserById(@PathParam("id") Long id) {
    return userService.getUserById(id);
}

}

Panache Entity Pattern

@Entity @Table(name = "users") public class User extends PanacheEntity {

@Column(nullable = false, unique = true)
public String email;

@Column(nullable = false)
public String name;

@Column(name = "created_at", updatable = false)
public LocalDateTime createdAt;

@PrePersist
void onCreate() {
    createdAt = LocalDateTime.now();
}

// Panache active record queries
public static Uni&#x3C;User> findByEmail(String email) {
    return find("email", email).firstResult();
}

public static Uni&#x3C;List&#x3C;User>> findActive() {
    return list("active", true);
}

}

DTO Records with Validation

public record UserRequest( @NotBlank(message = "Email is required") @Email(message = "Invalid email format") String email,

@NotBlank(message = "Password is required")
@Size(min = 8, max = 100, message = "Password must be 8-100 characters")
String password,

@NotBlank(message = "Name is required")
@Size(min = 2, max = 100)
String name

) {}

public record UserResponse( Long id, String email, String name, String role, boolean active, LocalDateTime createdAt ) {}

Exception Mapper Pattern

@Provider public class ResourceNotFoundMapper implements ExceptionMapper<ResourceNotFoundException> {

@Override
public Response toResponse(ResourceNotFoundException e) {
    return Response.status(Response.Status.NOT_FOUND)
        .entity(Map.of(
            "title", "Resource Not Found",
            "status", 404,
            "detail", e.getMessage(),
            "timestamp", Instant.now().toString()))
        .build();
}

}

Configuration

Application

quarkus.application.name=myproject quarkus.http.port=8080

Reactive datasource

quarkus.datasource.db-kind=postgresql quarkus.datasource.username=${DB_USERNAME:postgres} quarkus.datasource.password=${DB_PASSWORD:postgres} quarkus.datasource.reactive.url=vertx-reactive:postgresql://localhost:5432/mydb

JDBC (for Flyway migrations)

quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/mydb

Hibernate

quarkus.hibernate-orm.database.generation=validate quarkus.hibernate-orm.log.sql=true

Flyway

quarkus.flyway.migrate-at-start=true quarkus.flyway.locations=db/migration

Dev Services

%dev.quarkus.datasource.devservices.enabled=true %dev.quarkus.datasource.devservices.image-name=postgres:15-alpine

Logging

quarkus.log.level=INFO quarkus.log.category."com.example".level=DEBUG %prod.quarkus.log.console.json=true

JWT

mp.jwt.verify.publickey.location=publicKey.pem mp.jwt.verify.issuer=https://example.com

OpenAPI / Swagger

quarkus.smallrye-openapi.path=/api-docs quarkus.swagger-ui.always-include=true

Health

quarkus.smallrye-health.root-path=/health

Testing Overview

Standards

  • Use @QuarkusTest for integration tests (full CDI + HTTP stack)

  • Use @InjectMock to mock CDI beans in integration tests

  • Use @TestSecurity(user = "test", roles = "ADMIN") to bypass auth in tests

  • Use REST-assured for HTTP endpoint assertions

  • Use @QuarkusTestResource with Testcontainers for DB integration tests

  • Test native with ./mvnw verify -Pnative (runs @NativeImageTest classes)

  • Use @DisplayName for readable test names describing behavior

Integration Test

@QuarkusTest @DisplayName("UserResource") class UserResourceTest {

@Test
@DisplayName("POST /api/v1/users - should create user")
void shouldCreateUser() {
    given()
        .contentType(ContentType.JSON)
        .body(new UserRequest("test@example.com", "Password1!", "Test"))
    .when()
        .post("/api/v1/users")
    .then()
        .statusCode(201)
        .body("id", notNullValue())
        .body("email", equalTo("test@example.com"));
}

@Test
@TestSecurity(user = "admin", roles = "ADMIN")
@DisplayName("GET /api/v1/users - admin can list users")
void adminCanListUsers() {
    given()
    .when()
        .get("/api/v1/users")
    .then()
        .statusCode(200);
}

}

Commands

Create project

mvn io.quarkus.platform:quarkus-maven-plugin:3.6.0:create
-DprojectGroupId=com.example
-DprojectArtifactId=myproject
-Dextensions="resteasy-reactive-jackson,hibernate-reactive-panache,reactive-pg-client"

Dev mode (live reload + Dev Services)

./mvnw quarkus:dev

Run tests

./mvnw test

Build JVM jar

./mvnw package

Build native binary

./mvnw package -Pnative

Build native in container (no local GraalVM)

./mvnw package -Pnative -Dquarkus.native.container-build=true

Verify native (integration tests against native binary)

./mvnw verify -Pnative

List available extensions

./mvnw quarkus:list-extensions

Add extension

./mvnw quarkus:add-extension -Dextensions="openapi"

Build container image

./mvnw package -Dquarkus.container-image.build=true

Deploy to Kubernetes

./mvnw package -Dquarkus.kubernetes.deploy=true

Lint / format

./mvnw compile # Runs annotation processors mvn checkstyle:check # If checkstyle configured

Best Practices Summary

Do

  • Use Dev Services for automatic local containers

  • Use Panache for simpler data access patterns

  • Use reactive types (Uni , Multi ) for I/O-bound operations

  • Use @WithTransaction on service methods (not resources)

  • Configure for native compilation early; test regularly

  • Use health checks (@Liveness , @Readiness , @Wellness )

  • Use profile-based configuration (%dev. , %test. , %prod. )

  • Use MapStruct (compile-time) over reflection-based mappers

Do Not

  • Mix blocking calls in reactive pipelines (use @Blocking annotation if needed)

  • Use runtime reflection without @RegisterForReflection

  • Hardcode configuration values (use @ConfigProperty or @ConfigMapping )

  • Use synchronous JDBC APIs with reactive datasources

  • Ignore native build compatibility until deployment time

  • Put business logic in resource classes

Advanced Topics

For detailed patterns and examples, see:

  • references/patterns.md -- Reactive pipelines, Hibernate Reactive, testing strategies, GraalVM native, messaging, security, observability

External References

  • Quarkus Documentation

  • Quarkus Extensions

  • Panache Guide

  • RESTEasy Reactive Guide

  • SmallRye JWT

  • Native Compilation

  • Dev Services

  • MicroProfile Health

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

actix-web

No summary provided by upstream source.

Repository SourceNeeds Review
General

frontend-design

No summary provided by upstream source.

Repository SourceNeeds Review
General

blazor

No summary provided by upstream source.

Repository SourceNeeds Review