Files
ki-eit/07-quarkus-als-zweites-backend.md
grok-bot 8e00712fb8 Kapitel-Review (MUSS): Metriken, Golden Paths und eBook neu.
Composite-Korridore und Primärquellen in Kap. 2 ehrlich kalibriert;
DoD/Verify, Surfaces und Anhänge in 04–16 geschärft; eBook 119 S. neu gebaut.
2026-08-10 22:11:27 +02:00

27 KiB
Raw Permalink Blame History

7. Quarkus als zweites Backend

Kern: Quarkus ist hier zweites Backend-Profil — stark für cloud-native Services und schnelle Dev-Feedback-Loops. Kein stillschweigendes 1:1-Spring-Port.

Spring Boot bleibt in vielen Konzernen der Kern (Kap. 6). Daneben taucht Quarkus auf: neue Services, container-first, Dev-Mode-Tempo, kleinere deployable Units. Für Agents ist das Chance und Falle zugleich. Chance, weil klare, moderne Idiome und schnelle Tests gut zu Tight-Loops passen. Falle, weil der Agent Spring-Annotationen und Boot-Starters „mitbringt“, sobald das Repo die Grenze nicht laut zieht.

Quarkus als zweites Backend-Profil — kein 1:1-Spring-Port.{width=90%}

Dieses Kapitel ist bewusst kein Parallel-Vollbuch. Es klärt Entscheid, eigenständige Agent-Patterns, Port-Fallen und eine Migrations-Checkliste Spring → Quarkus — genug, damit Instructions und Golden Paths greifen. Wer nur Spring fährt, kann es überfliegen und bei Kap. 8 weiterlesen. Wer zwei Backend-Profile fährt, zahlt These 7 invers im Doppelpack: mehr Alignment, nicht „ein Prompt für beide“.

7.1 Wann Quarkus statt oder neben Spring

Die Entscheidung ist Team- und Plattform-Sache, kein Agent-Ranking. Die Tabelle hilft, die Debatte zu strukturieren — und festzuhalten, warum ein Service welches Profil hat, bevor der Agent im falschen Idiom codiert.

Tendenz zu Quarkus Tendenz zu Spring Boot
neue Services, container-first, Dev-Mode-Tempo großes Spring-Ökosystem im Bestand
Team will Extensions + continuous testing Konzern-Standard Spring, Skill-Tiefe, Platform-Starters
kleinere deployable Units Integration in bestehende Boot-Plattform
Jakarta-/Quarkus-native APIs im Team ok Spring-Security-/Data-Stack ist die eine Wahrheit

Neben Spring ist legitim — und teurer für Agents: zwei Idiome, zwei Verify-Welten, zwei Golden Paths. Das ist These 7 invers in Doppelpack: mehr Alignment, nicht Prompt-Länge.

Haltet die Kriterien in ADR, Platform-Docs und kurz in den jeweiligen AGENTS.md fest. Was nur in einem Architecture-Meeting steht, sieht der Agent nicht.

Zwei Profile im Monorepo / Multi-Repo

Die teure Variante ist nicht „Quarkus oder Spring“, sondern beide im selben Context ohne Grenze.

Setup Agent-Grenze Handoff
Multi-Repo (ein Service = ein Repo) Explore nur im Quarkus-Repo; Spring-Nachbar höchstens als Contract/Notiz Kap. 2.5, 8
Monorepo (Maven/Gradle multi-module) Package-Rules / path-scoped Rules pro Modul; kein Root-Text, der beide Stacks vermischt ein Slice pro Modul; Contract FE ↔ ein BE
Shared Library API-only; keine Framework-Annotations mischen eigene Ownership + eigenes Verify

Root-AGENTS.md darf sagen: „Backend-Profile pro Modul — siehe Modul-AGENTS.“ Es darf nicht versuchen, Spring- und Quarkus-Idiome in einer Wahrheit zu vereinen. Session-Regel: eine Session = ein Profil (Kap. 4, 8).

Bevorzugt: ein Backend-Profil pro Service; ADR + Instructions-Hinweis; Package-Rules/Repos getrennt; Handoff über Contract/Outcomes.
Vermeide: „Irgendwie JVM“; stiller Mix aus Spring- und Quarkus-Annotations; eine Root-Rule für beide Stacks; Spring-Controller als Copy-Paste-Context in die Quarkus-Session.

7.2 Agent-Patterns für Quarkus

Was im Repo laut sein muss, unterscheidet sich von Spring in den Details — nicht in der Logik (Kap. 4: eine Wahrheit, scoped Verify, Progressive Disclosure). Die folgenden Patterns sind eigenständig Quarkus: nicht nur „nicht Spring“, sondern was Agents hier konkret steuert.

Was Quarkus agent-tauglich macht, wenn das Repo mitspielt: schnelle scoped @QuarkusTest, Extensions-Disziplin (BOM = Wahrheit), Dev Services als Policy statt Automatismus, und die harte Trennung Continuous Testing / Dev-Mode ≠ Agent-DoD.

Eine REST-Linie und reaktiv vs. imperativ

RESTEasy Reactive / Jakarta-APIs oder bewusst Spring-Compatibility-Layer — nicht beides wild. Wenn Compatibility nein ist, gehört das in Immer/Nie: sonst portiert der Agent @RestController und ResponseEntity in den Quarkus-Service.

Reaktiv nur policy-gesteuert. RESTEasy Reactive heißt nicht automatisch Uni/Multi überall. Viele Teams bleiben beim imperativen Panache-Pfad (wie 7.3) — ein Return-Typ, weniger Blocking-Fallen. Fahrt ihr bereits reaktiv, setzt die Linie laut; sonst mischt der Agent Response und Uni<Response> oder blockiert im Event-Loop.

In AGENTS.md oft eine Zeile: REST-Rückgabe: imperativ (Default) | Uni/Multi (nur wenn Service so fährt).

Linie Return Persistenz Agent-Empfehlung
Imperativ (Default vieler Teams) Response / DTO Panache blocking + @Transactional Default, solange der Service so fährt
Reaktiv Uni<Response> / Multi Panache Reactive + withTransaction nur bei Repo-Default + Golden Path

Policy in einem Satz: eine Linie pro Service; imperativ, bis das Team reaktiv laut und mit Referenz-Resource fährt. Reaktiv lohnt, wenn Mutiny/Panache Reactive Repo-Default ist. Sonst ist der imperative Golden Path in 7.3 die imitierbare Wahrheit — Vollbeispiele nur dort zuerst.

Skeleton nur wenn euer Repo reaktiv fährt (kein Default-Vorbild zum Skimmen):

// Nur bei Repo-Default Uni/Multi — sonst 7.3
// @POST public Uni<Response> create(…) { return Panache.withTransaction(…); }
// Avoid: blockieren im Event-Loop; Mix Uni + imperatives persist()

Golden-Path-Resource und Tests müssen dieselbe Linie zeigen.

Extensions bewusst

Quarkus lebt von Extensions. Agents lieben „noch eine aus dem Guide“. Drei Stufen: (1) bestehende nutzen (BOM / pom.xml / Gradle des Service), (2) neue nur mit Auftrag + Review + eine Zeile Begründung, (3) Classpath-/Build-Risiko bedenken — jede Extension zieht Transitiven, Config-Keys und oft Dev Services nach.

Szene: Agent will quarkus-xyz im selben PR wie den Endpoint. Stoppsignale: neue quarkus-…-Dependency, unbekannte quarkus.*-Keys, Imports aus bisher ungenutzten Packages. Review-Frage: „Auftrag — oder Tutorial-Reflex?“ Task-Ausschluss: „keine neuen Extensions; nur bestehende aus diesem Service.“

Tests: @QuarkusTest scoped — nicht Continuous Testing als DoD

Tight-Loop = gezielte Testklasse mit Wrapper und Exit-Code, nicht „Dev-Mode läuft und sieht grün aus“. Continuous Testing und quarkusDev sind Mensch-Tempo: schnell, interaktiv, ungeeignet als agent-prüfbare Definition of Done (Kap. 2.2, 9). Der Agent braucht non-interactive Commands, die in CI denselben Exit-Code liefern.

# Tight-Loop (Agent-DoD) — scoped, non-interactive
./mvnw -q -Dtest=OrderResourceTest test

# Avoid als DoD:
# ./mvnw quarkus:dev
# Continuous Testing „grün im Terminal“ ohne Exit-Code an die Session

Dev Services & Testcontainers

Für @QuarkusTest startet Quarkus oft automatisch eine DB (Dev Services), wenn Docker da ist — gut für Menschen, für Agents Policy, kein Automatismus:

Policy Typisch Agent-Hinweis
Standard im Test DB via Dev Services, wenn Team so fährt im @QuarkusTest/Heavy ok; Logs nicht im Context
Nur mit Auftrag Kafka, Keycloak, weitere Broker nicht im Tight-Loop „zur Sicherheit“
CI Dev Services oder feste Testcontainers-Profile dieselbe Wahrheit wie Verify in AGENTS.md

Agent-Fallen: lange Start-Logs im Context; fehlender Docker-Daemon; interaktive Pulls; lokal grün, CI ohne Docker rot. Gegenmittel: non-interactive Verify, enger Scope, target/ und Container-Logs aus dem Context (Kap. 4).

@QuarkusTest
class OrderResourceTest {
    @Test
    void create_returns201() {
        given().contentType(ContentType.JSON)
            .body("{\"items\":[\"sku-1\"]}")
        .when().post("/api/orders")
        .then().statusCode(201);
    }
}
// test application.properties: quarkus.datasource.devservices.enabled=true
// Agent: ./mvnw -q -Dtest=OrderResourceTest test — nicht quarkusDev

Native-Image nur mit klarem Auftrag

Native-Builds sind langsam, tool-schwer und agent-teuer (Context voller Build-Logs). Slice-DoD bleibt JVM-package mit -DskipTests wo sinnvoll; Native = Heavy/Sonderpfad (siehe 7.4).

Stufe Beispiel-Muster (Maven) Gradle-Äquivalent Agent-Hinweis
Tight-Loop ./mvnw -q -Dtest=OrderResourceTest test ./gradlew test --tests …OrderResourceTest Exit-Code; kein Dev-Mode als DoD
Slice-DoD ./mvnw -q -DskipTests package ./gradlew build -x test baut; Diff = Auftrag
Heavy ./mvnw verify (+ Dev Services/TC nach Policy) ./gradlew build / check vor Merge / CI
Native (Auftrag) ./mvnw package -Dnative nur mit Auftrag / Team-Plugin nicht im Tight-Loop

Config: properties, Profile, keine Spring-Keys

„Nimm die Config vom Spring-Service mit“ endet oft in spring.datasource.*, gemischter properties/YAML-Lage und Boot-Profile-Erwartung. Gegenmittel: eine Config-Form, nur quarkus.* (+ Keys, die der Service schon nutzt), Profile als %dev/%test, Secrets nie im Diff.

# application.properties — GOLDEN Muster (kein Spring-Key)
quarkus.datasource.db-kind=postgresql
quarkus.hibernate-orm.database.generation=none
%test.quarkus.datasource.devservices.enabled=true
# Avoid: spring.datasource.url=… ; Secrets; properties+yml parallel ohne Not

In AGENTS.md: Config-Form: application.properties | yaml (eine Wahrheit).

Security / OIDC: Quarkus-Idiom, nicht Spring-Security-Denkweise

Security-Invariants sind profil-unabhängig (Kap. 12). Das Idiom ist es nicht. Agents portieren gerne SecurityFilterChain, permitAll „erstmal zum Testen“ oder Spring-Security-Annotationen in den Quarkus-Service.

Anker (Muster, Stand Mitte 2026 — an eure Extension-Generation anpassen):

// OrderResource — OIDC/Roles laut Repo (Quarkus Security)
@Path("/api/orders")
@Authenticated
public class OrderResource {

    @POST
    @RolesAllowed("order-write")
    @Transactional
    public Response create(CreateOrderRequest request) {
        Order order = Order.createNew(request.items());
        order.persist();
        return Response.status(Response.Status.CREATED)
                .entity(OrderResponse.from(order)).build();
    }
}
# nur Keys/Extensions, die der Service schon nutzt — keine Shopping-Tour im Feature-PR
# quarkus.oidc.auth-server-url=${OIDC_AUTH_SERVER_URL}
# quarkus.oidc.client-id=${OIDC_CLIENT_ID}
# Avoid: offene permission-policy „permit“ zum Testen; Spring Security APIs;
#        Security „später“ und Endpoint schon produktiv erreichbar

Bevorzugt: bestehende OIDC-/Security-Extension + Rollen-Annotationen des Services; Policies aus dem Golden Path; Security-Diff Ampel gelb/rot (Kap. 12).
Vermeide: Spring-Security-APIs / permitAll-Reflex; Security „später“ bei schon offenem Endpoint; neue Security-Extension im Feature-PR ohne Auftrag.

Vertiefung Permissions, Secrets, HITL: Kap. 12. Hier reicht der Idiom-Anker, damit der Agent nicht Boot-Security denkt.

Vorlagen: templates/agents-md-quarkus.md; optional Surface Copilot: templates/copilot-instructions-quarkus.md (Surfaces: Anhang C). Checkliste: checklists/dod-quarkus.md. Coding-Style-Skill: templates/skill-quarkus-coding-style/.

Quarkus-Session-Check

  • scoped -Dtest= / --tests + Wrapper — nicht Continuous Testing / quarkusDev als DoD
  • keine neue quarkus-…-Extension ohne Auftrag
  • Dev Services = Team-Default; Rest on request
  • eine REST-/Persistenz-Linie; reaktiv nur bei Repo-Default
  • nur quarkus.*-Keys — keine Spring-Config-Nostalgie

7.3 Die Session, die Spring nach Quarkus kopiert

Doppel-Alignment-Schmerz: „Bau denselben Endpoint wie im Spring-Service, aber in Quarkus.“ Der Agent liefert @RestController / @Autowired / JpaRepository, Boot-actuator-Mentalität und application.yml-Keys aus dem Nachbarrepo. Compilieren mag sogar mit Compatibility-Layer klappen — idiomatisch und wartbar ist es oft nicht. These 7 invers gilt hier zweimal: zwei Idiome, zwei Verify-Welten. Stopp-Kriterium ist nicht „noch ein Port-Fix“, sondern: Spring-Fremdkörper raus, Golden Path (Jakarta REST + CDI + Panache) an, frische Session am Quarkus-Referenzpfad (Kap. 2.1, 6).

Mini-Diff: Spring-Port vs. idiomatischer Endpoint

Gleiche Fachaufgabe, zwei Idiome — passend zur Szene oben. Der Agent-Port „fühlt“ sich an wie der Spring-Service von nebenan. Der Golden Path bleibt bei Jakarta REST + CDI + Panache — die Linie, die euer Quarkus-AGENTS.md als Default setzt (Spring-Compatibility: nein). Reaktive Uni/Multi nur, wenn euer Service so fährt; hier knapper imperativer Pfad mit Panache Active Record, damit der Diff lesbar bleibt. Policy und reaktives Mini-Beispiel: 7.2.

Auftrag: „In Quarkus: POST /api/orders legt eine Order an (wie im Spring-Service).“

Agent-Output (typisch)

// OrderController.java — AGENT: Spring-Idiom 1:1 „portiert“
@RestController
@RequestMapping("/api/orders")
public class OrderController {

    @Autowired
    private OrderRepository orderRepository;

    @PostMapping
    public ResponseEntity<Order> create(@RequestBody Order body) {
        body.setStatus("NEW");
        body.setCreatedAt(Instant.now());
        Order saved = orderRepository.save(body);
        return ResponseEntity.status(HttpStatus.CREATED).body(saved);
    }
}

// OrderRepository.java — Spring Data Mentalität
public interface OrderRepository extends JpaRepository<Order, Long> {}

// Order.java
@Entity
public class Order {
    @Id @GeneratedValue
    private Long id;
    private String status;
    private Instant createdAt;
    // …
}

Ohne Spring-Compat kompiliert das in Quarkus nicht. Mit Compat kompiliert es — und ihr habt zwei Backend-Wahrheiten in einem Profil.

Golden Path (gewünscht)

// OrderResource.java — GOLDEN: Jakarta REST + CDI
@Path("/api/orders")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class OrderResource {

    @POST
    @Transactional
    public Response create(CreateOrderRequest request) {
        Order order = Order.createNew(request.items());
        order.persist();
        return Response.status(Response.Status.CREATED).entity(OrderResponse.from(order)).build();
    }
}

// CreateOrderRequest.java / OrderResponse.java — API ≠ Persistenz-Detail
public record CreateOrderRequest(
        @NotEmpty List<@NotBlank String> items) {}

public record OrderResponse(Long id, String status, Instant createdAt, List<String> items) {
    static OrderResponse from(Order o) {
        return new OrderResponse(o.id, o.status, o.createdAt, o.items);
    }
}

// Order.java — Panache entity (Active Record; Repository-Variante ok, wenn Repo so fährt)
@Entity
public class Order extends PanacheEntity {
    public String status;
    public Instant createdAt;
    @ElementCollection
    public List<String> items;

    public static Order createNew(List<String> items) {
        if (items == null || items.isEmpty()) {
            throw new BadRequestException("items required");
        }
        Order o = new Order();
        o.status = "NEW";
        o.createdAt = Instant.now();
        o.items = List.copyOf(items);
        return o;
    }
}

Imports und Extensions kommen aus dem bestehenden Service (quarkus-rest / RESTEasy Reactive, Hibernate ORM with Panache) — keine neue Extension „weil das Tutorial sie hatte“. Verify: scoped @QuarkusTest auf OrderResource, nicht Dev-Mode als DoD.

Analyse + Gegenmittel (ein Block): Spring-Annotationen/JpaRepository im Quarkus-Modul = Build-Bruch oder Compat-Wildwuchs; nächste Session portiert denselben Fehler. Golden Path: eine REST-/Persistenz-Linie, @QuarkusTest + Wrapper, Ausschluss „kein Spring-Compat“ im Diff sichtbar. Lenken: Quarkus-AGENTS.md (Jakarta; Compat: nein; Referenz-Resource), Task-Ausschluss kein @RestController, Explore nur im Quarkus-Modul, Spring höchstens als Handoff-Notiz. Skill templates/skill-quarkus-coding-style/; Vorlage templates/agents-md-quarkus.md. Teach-back am selben Tag in eigener Session (Kap. 3.3), nicht im Port-PR. Do: Referenz-Resource + Test in Dateien mit Vorrang; Compat-Policy ja/nein schriftlich; Dev Services nach Team-Policy im Heavy. Avoid: Spring-Controller 1:1; Compat „kurz“; Dev-Mode als CI-Wahrheit.

Mini-Diff: Panache Active Record vs. Repository

Neben dem Port-Fehler gibt es eine zweite, legitime Entscheidung innerhalb von Quarkus: Active Record oder Repository. Beide sind idiomatisch — der Agent soll eure eine Wahrheit treffen, nicht Tutorial-X.

Variante Wann Agent-Hinweis
Active Record (PanacheEntity, order.persist()) viele kleine Services; Default in 7.3 oben Golden Path imitieren
Repository (PanacheRepository<Order>) Team will Query-Objekte / dünnere Entities @Inject OrderRepository; Entity ohne AR-API

Repository-Variante (wenn euer Service so fährt):

// OrderRepository.java — GOLDEN wenn Repo-Default = Repository
@ApplicationScoped
public class OrderRepository implements PanacheRepository<Order> {
    // Query-Methoden hier, nicht wild in der Resource
}

// OrderResource.java — CDI + Repository
@Path("/api/orders")
public class OrderResource {

    @Inject
    OrderRepository orders;

    @POST
    @Transactional
    public Response create(CreateOrderRequest request) {
        Order order = Order.createNew(request.items());
        orders.persist(order);
        return Response.status(Response.Status.CREATED)
                .entity(OrderResponse.from(order)).build();
    }
}

// Order.java — Entity ohne PanacheEntity, wenn Repository-Linie
@Entity
public class Order {
    @Id @GeneratedValue
    public Long id;
    public String status;
    public Instant createdAt;
    // createNew(…) wie gehabt
}

Analyse (kurz)

  • Beide ok, solange eine Persistenz-Linie im Service gilt und im Golden Path steht.
  • Agent-Falle: AR in der einen Resource, Repository in der nächsten „für Flexibilität“ — Review zahlt zwei Idiome.
  • Lenken: In AGENTS.md: Persistenz: Panache Active Record | PanacheRepository (eine Wahl) + Referenz-Datei.

Im Review stoppt: AR und Repository parallel im selben Modul ohne Not; Tutorial-Persistenz, die vom Service-Default abweicht.
Nit: Active-Record vs. Repository als Team-Wahl — solange eine Linie und ein Referenz-Pfad gelten.

7.4 Fallen und Hygiene

Falle Warum es wehtut Gegenmittel
Spring-Annotationen blind zweite Wahrheit, Review-Chaos Idiom-Linie + Code-Beispiele (7.3)
Extension-Shopping undurchsichtige Deps, längere Builds, stille Config-Keys „nur mit Auftrag“ in Instructions; Diff auf quarkus-… scannen
Dev-Mode ≠ CI Agent „sieht grün“, Pipeline rot non-interactive Maven-Wrapper-Commands mit Exit-Code
Native ohne Need teure Loops, Context-Müll Native nur bei explizitem Outcome
Config Spring→Quarkus spring.*-Keys, Profile-Chaos, Secrets eine Config-Form; nur quarkus.*; 7.2
Security offen OIDC/Roles „später“ Security-Invariants wie in Spring (Kap. 12); Idiom 7.2
Zwei Profile, eine Session Context-Mix, Port-Nostalgie Session = ein Profil; Handoff (7.1)
Secrets in properties Klassiker, auch unter Quarkus Nie in Beispielen/Chat

Extension-Stopp im Review. Neue quarkus-…-Dependency oder unbekannter Config-Key im Diff ist Scope, kein Stil-Nit. Frage: „Welche bestehende Extension hätte dasselbe gelöst?“ Ohne Auftrag: ablehnen oder eigenen Change — nicht im Feature-PR mitnehmen.

Native/AOT und Security — kurz. Native bleibt Heavy-Sonderpfad (eigener Auftrag, eigene Pipeline-Stufe). Security-Invariants (OIDC, Rollen, keine offenen Management-Endpoints „zum Testen“) gelten profil-unabhängig; Vertiefung: Kap. 12.

Runtime / Einstieg gilt wie überall (Kap. 4.1): JDK-Pin, Wrapper, dieselben Commands in Instructions und CI. Fehlende non-interactive Commands in AGENTS.md sind die banale Falle, die Sessions mit Installer-Prompts und falschem mvn vom Host killt.

7.5 Migrations-Checkliste Spring → Quarkus

Wenn ein Service von Spring nach Quarkus soll (oder ein Zwilling neu entsteht), reicht der Mini-Diff 7.3 als Warnschild — nicht als Projektplan. Die Checkliste ist Team-Ritual: vor dem ersten Port-PR abhaken, nicht dem Agent als Autopilot überlassen.

Framework-Wechsel innerhalb Legacy: enge Slices und Fassaden bleiben Kap. 11; hier geht es um Idiom, Verify und Repo-Wahrheit des neuen Profils.

Idiom-Übersetzung (Lookup)

Spring (typisch) Quarkus (Default-Linie dieses Buchs)
@RestController / ResponseEntity Jakarta REST @Path / Response
@Autowired / Spring DI CDI @Inject / Constructor nach Repo-Idiom
JpaRepository Panache Active Record oder PanacheRepository (eine Wahl)
Spring Security / SecurityFilterChain Quarkus OIDC / @Authenticated / @RolesAllowed
application.yml + spring.* application.properties (oder eine YAML-Wahrheit) + quarkus.*
@SpringBootTest / @WebMvcTest @QuarkusTest (+ Unit wo sinnvoll)
Spring-Starter Quarkus Extension (nur bestehende oder beauftragte)
Actuator-Mentalität „alles offen zum Testen“ Management-Endpoints bewusst; Security-Invariants (Kap. 12)

Checkliste (kopierbar)

  • 1. Scope & Entscheid. Portieren vs. neu bauen? Service-Grenze klar? ADR-Zeile: warum Quarkus, warum dieser Service zuerst — und was nicht im ersten Slice liegt.
  • 2. Idiom-Inventar (Handoff, kein Dump). Aus dem Spring-Service listen: REST-Layer, Persistenz, Security, Config-Keys, Test-Schnitt. Als kurze Handoff-Notiz — nicht den ganzen Controller-Baum in die Quarkus-Session laden (Kap. 2.5, 4).
  • 3. Idiom-Übersetzung festlegen. Tabelle oben an euer Team anpassen; eine REST-Linie, eine Persistenz-Variante (AR vs. Repository), Compat: ja/nein (Default-Empfehlung hier: nein).
  • 4. AGENTS.md / Package-Rules anpassen. REST-Linie; Spring-Compatibility: nein (oder bewusst ja + Begründung); reaktiv: ja/nein; Config-Form; Persistenz-Variante; Verify-Commands; Dateien mit Vorrang (Golden-Path Resource + Test). Surfaces mappen (Anhang C).
  • 5. Extensions-Inventur. Ist-pom.xml / Gradle des Ziel-Service = Wahrheit. Immer/Nie: „keine neuen Extensions ohne Auftrag.“ Diff auf neue quarkus-…-Deps scannen.
  • 6. Verify & DoD umstellen. Tight-Loop: scoped @QuarkusTest + Wrapper; Slice-DoD: package/build -x test; Heavy: verify/check. Continuous Testing und quarkusDev nicht als Agent-DoD (Kap. 9). Checkliste checklists/dod-quarkus.md.
  • 7. Erster dünner Slice. Ein Endpoint + Test am Golden Path (7.3) — kein Big-Bang-Port aller Controller. DoD: grüner scoped Test + Diff = Auftrag.
  • 8. Test- & Handoff-Strategie. Spring-Session beenden → Handoff (Contract, Outcomes, offene Risiken) → neue Quarkus-Session. Explore nur im Quarkus-Modul. Multi-Repo/Monorepo-Grenzen aus 7.1 einhalten.
  • 9. Review-Ampel. Spring-Fremdkörper / ungebetener Compat = Blocker. Security-, Config- und Extension-Delta = gelb/rot (Kap. 12). Native nur mit eigenem Auftrag.
  • 10. Teach-back & Write-Back. Nach 2–3 gleichen Port-Fehlern: Rule/Skill schärfen (Kap. 3.3), Golden Path und Ausschlüsse nachziehen — nicht nur PR-Kommentare stapeln.

Quarkus Golden Path Checklist

Für neuen Quarkus-Service oder nach gelungenem Erst-Slice (analog Greenfield-Defaults Kap. 11 — hier profil-spezifisch):

  • REST-Linie + Spring-Compatibility ja/nein in AGENTS.md
  • reaktiv ja/nein; Persistenz AR oder Repository (eine Wahl)
  • Golden-Path Resource + @QuarkusTest verlinkt (Dateien mit Vorrang)
  • Verify Tight / Slice-DoD / Heavy (Maven oder Gradle — eine Wahrheit)
  • Extension-Policy + Dev-Services-Policy (Standard vs. on request)
  • Security-Invariants (OIDC/Roles; keine offenen Management-Endpoints „zum Testen“)
  • Config ohne Secrets; eine Config-Form; keine spring.*-Keys
  • Native nur mit Auftrag; Continuous Testing ≠ Agent-DoD

Key Takeaways

  • Quarkus = zweites Profil mit eigenen Idiomen, nicht Spring-Klon und nicht Agent-Sweet-Spot-Automatismus.
  • Eine REST-Linie; reaktiv nur policy-gesteuert — Default oft imperativ Panache (7.3); Uni/Multi nur bei Repo-Default.
  • Patterns: Panache AR oder Repository, Config ohne Spring-Keys, OIDC/@RolesAllowed — eine Wahrheit pro Service.
  • Extensions neu nur mit Auftrag; Mini-Diff (7.3): Spring-Port-Nostalgie vs. Jakarta REST + CDI + Panache.
  • Agent-DoD: scoped @QuarkusTest + Wrapper/Exit-Codes — Continuous Testing ≠ Agent-DoD; zwei Profile = doppelte Alignment-Pflicht + Handoff.
  • Migrations-Ritual (7.5): Scope → Idiom → AGENTS.md → Extensions → Verify → dünner Slice → Ampel → Teach-back.

Praktische nächste Schritte

  1. Entscheidungskriterien Spring vs. Quarkus teamweit festhalten (ADR) und pro Service in Instructions/AGENTS.md spiegeln; Monorepo/Multi-Repo-Grenzen (7.1) benennen.
  2. templates/agents-md-quarkus.md anpassen: REST-Linie, Compat ja/nein, reaktiv ja/nein, Persistenz AR/Repository, Config-Form, Maven- oder Gradle-Verify; optional Surface Copilot: templates/copilot-instructions-quarkus.md; Surfaces mappen (Anhang C).
  3. Einen kleinen Service (Resource + @QuarkusTest) als Golden Path markieren — dieselbe Rückgabe- und Persistenz-Linie wie in Production; Golden Path Checklist (7.5) abhaken.
  4. Den Mini-Diff aus 7.3 einmal als Teach-back fahren; Compat-Policy und Ausschluss „kein @RestController“ schriftlich machen.
  5. Migrations-Checkliste 7.5 an einem Kandidaten-Service dry-runen (auch wenn der Port noch Wochen entfernt ist) — Lücken in AGENTS.md und Verify werden sofort sichtbar.
  6. Extension-Policy und Dev-Services-Policy (Standard vs. on request) in Immer/Nie; Checkliste checklists/dod-quarkus.md legen; Continuous Testing vs. Agent-DoD im Team klären.
  7. Danach Kap. 8 — vertikale Slices über Angular und das gewählte Backend, inkl. Contract.

Quarkus neben Spring funktioniert mit Agents, wenn die Grenze im Repo lauter ist als die Spring-Erinnerung im Modell — und wenn der Port ein Checklist-Ritual ist, kein Hoffen auf 1:1-Übersetzung. Ab Kapitel 8 geht es um den Schnitt über den Stack — unabhängig davon, welches JVM-Profil unten liegt.