Awesome_IA_Rules / backend
Cursor rule1 starsChanged 3 days agoMITView on GitHub
Java 21+ and Quarkus backend standards, Hexagonal Architecture, CDI, Panache, Virtual Threads, and testing
Where files are headingNew Cursor rule files have more rules about planning and tracking tasks, and fewer about code style.
Of the Cursor rule files we read, the 4,144 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository8 other files it gives its agents.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- .cursor/rules/backend/go-backend.mdcCursor rule
- .cursor/rules/backend/node-bff-backend.mdcCursor rule
- .cursor/rules/core/01-core-engineering.mdcCursor rule
- .cursor/rules/core/02-spec-driven-development.mdcCursor rule
- .cursor/rules/core/03-code-review.mdcCursor rule
- .cursor/rules/frontend/node-react-frontend.mdcCursor rule
The file
Show its rules and text
We split this java-quarkus-backend.mdc into the rules it gives an agent
15 rules. About 0 are common, 0 are distinctive, and 15 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
15
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 41
Java Records for Immutability: Use record for all Value Objects, Commands, Queries, Request/Response DTOs, and Domain Events.
- Very specific: line 56
Sealed Interfaces & Pattern Matching: Use sealed interface and exhaustive switch expressions for domain states, payment methods, or typed …
- Very specific: line 58
Null Safety: Never return null from collections (return List.of()) or optional lookups (return Optional<T>).
- Very specific: line 65
Constructor Injection Only: Always use constructor injection with final fields.
- Very specific: line 69
Keep the domain package free of CDI annotations where possible, or wire domain services via @Produces in an infrastructure configuration …
- Very specific: line 72
Prefer @ConfigMapping(prefix = "app.payment") interfaces over scattered @ConfigProperty annotations to group and validate configuration at …
- Very specific: line 84
Avoid dynamic reflection (Class.forName, MethodHandles), runtime bytecode generation, or unannotated serialization classes.
- Very specific: line 85
If a third-party DTO requires reflection in GraalVM native mode, annotate with @RegisterForReflection.
- Very specific: line 92
Strict Separation: Never annotate Domain Entities with @Entity or @Table.
- Very specific: line 94
Transaction Boundaries: Place @Transactional at the Application Command Handler boundary (execute method).
- Very specific: line 95
Prevent N+1 Queries: Use FetchType.LAZY on all associations (@ManyToOne, @OneToMany) by default, and use explicit JOIN FETCH queries or …
- Very specific: line 111
Test Domain Entities, Value Objects, Domain Services, and Application Handlers using plain JUnit 5 + Mockito + AssertJ …
- Very specific: line 112
Do not boot @QuarkusTest for domain or application unit tests—keep unit test execution under milliseconds.
- Very specific: line 114
Use @QuarkusTest with RestAssured and Quarkus Dev Services / Testcontainers for REST entrypoints, database repositories, and messaging …
- Very specific: line 115
Use @InjectMock sparingly, only for external outbound boundaries.
≈ “Common” is an estimate: at least 1 in 5 of the 6,668 Cursor rule files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
---
description: "Java 21+ and Quarkus backend standards, Hexagonal Architecture, CDI, Panache, Virtual Threads, and testing"
globs: "**/*.java"
alwaysApply: false
---
# Java & Quarkus Backend Engineering Standards
> **Scope**: All Java (`*.java`) source, test, and configuration (`application.properties` / `application.yaml`) files.
> **Mandate**: Build cloud-native, GraalVM native-image compatible, high-throughput applications using Modern Java (21+) and Quarkus build-time optimization principles within a Clean/Hexagonal Architecture.
---
## 1. Project Structure & Hexagonal Architecture
Maintain strict inward dependency flow: `infrastructure/entrypoint → application → domain`.
```text
src/main/java/com/acme/service/
├── domain/ # Pure Java (Zero Quarkus/JPA/Jackson annotations)
│ ├── model/ # Entities, Aggregate Roots, Value Objects (Records)
│ ├── exception/ # Semantic Domain Exceptions (Conflict, Validation, NotFound)
│ ├── service/ # Stateless cross-entity Domain Services
│ └── port/ # Repository & Core Domain Capability interfaces
├── application/ # Use Case Orchestration (CDI @ApplicationScoped)
│ ├── command/ # Write Command Handlers & Command DTOs
│ ├── query/ # Read Query Handlers & Read Models
│ └── port/ # Outbound Gateway & Integration interfaces
└── infrastructure/ # Quarkus & External Adapters
├── entrypoint/rest/ # Jakarta REST (@Path), Request/Response Records, ExceptionMappers
├── entrypoint/messaging/ # SmallRye Reactive Messaging consumers/producers
├── persistence/ # Panache/JPA Entities, Repositories, Entity Mappers
├── client/ # Quarkus REST Client (@RegisterRestClient) & Adapters
└── config/ # @ConfigMapping typed configuration interfaces
```
---
## 2. Modern Java (Java 21+) Idioms
- **Java Records for Immutability**: Use `record` for all Value Objects, Commands, Queries, Request/Response DTOs, and Domain Events. Enforce compact constructor validation on Value Objects:
```java
public record Money(BigDecimal amount, String currency) {
public Money {
Objects.requireNonNull(amount, "amount is required");
Objects.requireNonNull(currency, "currency is required");
if (amount.compareTo(BigDecimal.ZERO) <= 0) {
throw new DomainValidationException("amount must be greater than zero");
}
if (currency.length() != 3) {
throw new DomainValidationException("currency must be a 3-letter ISO code");
}
}
}
```
- **Sealed Interfaces & Pattern Matching**: Use `sealed interface` and exhaustive `switch` expressions for domain states, payment methods, or typed outcomes instead of deep class hierarchies or `instanceof` chains.
- **Virtual Threads (`@RunOnVirtualThread`)**: For I/O-bound blocking workloads on Java 21+, prefer Quarkus Resteasy Reactive with `@RunOnVirtualThread` over complex reactive chains (`Uni`/`Multi`), unless true backpressure streaming is required. Avoid `synchronized` blocks around I/O to prevent carrier thread pinning (use `ReentrantLock` if needed).
- **Null Safety**: Never return `null` from collections (return `List.of()`) or optional lookups (return `Optional<T>`). Never pass `Optional` as a method parameter or field.
---
## 3. Quarkus & CDI Best Practices (Build-Time First)
### Dependency Injection (ArC)
- **Constructor Injection Only**: Always use constructor injection with `final` fields. Never use `@Inject` on fields or setters (breaks testability and immutability). Omit `@Inject` when a single constructor exists.
- **Explicit Bean Scopes**:
- `@ApplicationScoped` for stateless use cases, adapters, and repositories.
- `@RequestScoped` only when request-bound state is strictly necessary.
- Keep the `domain` package free of CDI annotations where possible, or wire domain services via `@Produces` in an infrastructure configuration class.
### Typed Configuration
- Prefer `@ConfigMapping(prefix = "app.payment")` interfaces over scattered `@ConfigProperty` annotations to group and validate configuration at startup:
```java
@ConfigMapping(prefix = "app.payment-gateway")
public interface PaymentGatewayConfig {
URI baseUrl();
Duration timeout();
@WithDefault("3")
int maxRetries();
}
```
### Native Image Compatibility
- Avoid dynamic reflection (`Class.forName`, MethodHandles), runtime bytecode generation, or unannotated serialization classes.
- If a third-party DTO requires reflection in GraalVM native mode, annotate with `@RegisterForReflection`.
---
## 4. Persistence, REST & Resilience
### Persistence (Hibernate ORM with Panache)
- **Strict Separation**: Never annotate Domain Entities with `@Entity` or `@Table`. Keep JPA/Panache entities (`*JpaEntity`) inside `infrastructure.persistence`, and map explicitly to/from Domain models (using MapStruct or dedicated static mappers).
- **Repository Pattern**: Implement `PanacheRepositoryBase<PaymentJpaEntity, UUID>` rather than the Active Record pattern to keep persistence logic testable and decoupled.
- **Transaction Boundaries**: Place `@Transactional` at the Application Command Handler boundary (`execute` method). Use `@Transactional(Transactional.TxType.SUPPORTS)` or read-only queries for read paths.
- **Prevent N+1 Queries**: Use `FetchType.LAZY` on all associations (`@ManyToOne`, `@OneToMany`) by default, and use explicit `JOIN FETCH` queries or projections (`project(ReadModel.class)`) when loading relations.
### REST Entrypoints & Error Handling (RFC 9457)
- Validate inbound DTOs at the REST boundary using Jakarta Bean Validation (`@Valid`, `@NotBlank`, `@Positive`, `@Size`).
- Implement a centralized `@ServerExceptionMapper` that maps Domain/Application exceptions and `ConstraintViolationException` to **RFC 9457 `ProblemDetails`** JSON responses (`type`, `title`, `status`, `detail`, `code`, `errors`).
- **Proximity Logging**: Log infrastructure/database/client failures once at the adapter/repository source using `org.jboss.logging.Logger` with MDC context (`traceId`, `entityId`). Never re-log in use cases or controllers, and never expose internal exception messages on `500 Internal Server Error`.
### Outbound Clients & Fault Tolerance
- Declare outbound HTTP integrations using `@RegisterRestClient` interfaces.
- Apply SmallRye Fault Tolerance annotations (`@Timeout`, `@Retry` with jitter, `@CircuitBreaker`) on idempotent outbound operations.
---
## 5. Testing Standards (JUnit 5, Mockito & QuarkusTest)
- **Fast Unit Tests (`*Test.java`)**:
- Test Domain Entities, Value Objects, Domain Services, and Application Handlers using **plain JUnit 5 + Mockito + AssertJ** (`@ExtendWith(MockitoExtension.class)`).
- Do **not** boot `@QuarkusTest` for domain or application unit tests—keep unit test execution under milliseconds.
- **Integration & Contract Tests (`*IT.java` / `*ResourceTest.java`)**:
- Use `@QuarkusTest` with **RestAssured** and Quarkus Dev Services / Testcontainers for REST entrypoints, database repositories, and messaging adapters.
- Use `@InjectMock` sparingly, only for external outbound boundaries.
- **Conventions**:
- Naming: `should<ExpectedOutcome>_when<Condition>()`.
- Structure: Strict **Arrange-Act-Assert (AAA)** with fluent test Builders (`PaymentTestBuilder`) and AssertJ assertions (`assertThat(...)`, `assertThatThrownBy(...)`).
- Determinism: Inject `java.time.Clock` into domain/application classes instead of calling `Instant.now()` or `LocalDateTime.now()` directly.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

