Business operations¶
Submitting a customer application and looking up its status are different operations. Give each a typed contract, keep HTTP translation in the controller, and put the application behavior in a handler.
Start with one command and one query¶
The smallest demonstrated path uses CQRS, WebFlux, and Jakarta validation. The first-service POM declares those dependencies without adopting a database, message broker, or workflow engine.
Follow the complete onboarding tutorial:
- Submit
applicantNameandemailtoPOST /applications. - Let
CommandBusdispatchSubmitApplicationto the application handler. - Return the created record and its
Locationheader. - Send
GET /applications/{id}throughQueryBusand retrieve the same record.
The application repository in that project is an in-memory map. The buses structure execution; they do not make the record durable or a submission idempotent.
Verify the operation before adding more layers¶
The runnable tests check the HTTP result, invalid input, missing records, and the real command/query handlers. The authoritative code and tests live together in docs/examples/getting-started.
The CQRS reference explains command IDs, execution context, validation and authorization hooks. Keep business permission decisions in the service. Command.authorize() permits by default, so a protected operation needs a policy and trusted identity context.
Choose how business rules will change¶
| Situation | Choice |
|---|---|
| A small rule changes with the application | Keep it in the handler or domain model and test it there |
| Rules are represented in the framework's YAML DSL | Read the rule-engine core before adopting its evaluator |
| Another service owns rule evaluation | Use the rule-engine SDK against a configured rule-engine HTTP service |
| The operation spans work with compensations or reservations | Follow business coordination |
The rule-engine family includes separate contracts, storage models, an HTTP application, and a generated client. Select the concrete child artifact for the layer you are adding. A generated SDK does not run the remote service.
Event publishing and query caching are optional integrations. Their annotations and beans must be configured; broker delivery does not automatically invalidate a local query cache. Review the request flow before depending on those paths.
Next, choose domain and data when the application needs durable state or a reconstructable history.