Designing a Multi-Framework Portability Test with a Vending Machine Domain
TeaQL aims to keep domain models and generated business APIs independent of the web framework. The vending-machine-service example gives us a concrete way to test that claim across Spring Boot, Quarkus, and Micronaut.
This article defines what the portability test must prove and separates architectural intent from verified evidence.
The Setup
The test starts with one vending.xml model describing machines, products, inventory, transactions, and orders.
It then generates three separate web applications:
005-vending-machine-web-spring-boot;006-vending-machine-web-quarkus;007-vending-machine-web-micronaut.
The test may point all three applications at an isolated PostgreSQL schema to compare behavior. That shared schema is a test fixture, not a recommendation that independently deployed services share one production database.
A Shared Core
At the heart of the test is the java-lib-core module. The entities, expressions, checkers, and UserContext contract should be generated from the same model for every framework target.
Generated SmartList, SearchRequest, and expression APIs give each application the same domain vocabulary. Portability does not mean that the complete application outputs are byte-for-byte identical: HTTP routing, dependency injection, configuration, and lifecycle code remain framework-specific.
Framework Adaptation
The framework adapters follow distinct lifecycle and dependency-injection models:
- In Spring Boot, the intended runtime path uses
SpringJdbcSqlExecutorwithNamedParameterJdbcTemplate. - In Quarkus, the intended path uses the framework-neutral
teaql-provider-jdbcadapter with an Agroal data source and CDI producers. - In Micronaut, the intended path uses the same JDBC adapter with
@Singletonbean definitions and the configured JDBC data source.
What the Test Must Verify
A useful portability test needs more than successful generation. Each target must pass the same gates:
- evaluate the shared model with no blocking diagnostics;
- generate the domain core and selected web target;
- compile and run the generated tests on Java 21;
- start against a clean PostgreSQL test schema;
- execute the same intent-declared read;
- execute the same
.audit_as()mutation; - compare persisted state, API response, and audit output;
- preserve the commands and logs as evidence.
The framework-specific code is allowed to differ. The test fails when those differences leak into domain behavior or require hand-editing generated entities.
Current Evidence
The TeaQL service catalog inspected on 2026-07-13 advertised java-web-spring-boot, java-web-quarkus, and java-web-micronaut. Catalog presence proves target discoverability, not a clean build.
The same repository verification found generator/runtime alignment blockers in the Java core output. Until each application has a preserved clean-build and runtime smoke-test report, we should describe this as the portability test design and target architecture, not as a completed end-to-end validation.
Current verified combinations and blockers are tracked in the compatibility matrix. Once all three targets pass the gates above, the vending-machine test can provide meaningful evidence that teams may change framework adapters without rewriting their generated domain contract.
