Introduction to Apache Causeway
Building an enterprise application often involves implementing the same infrastructure repeatedly: domain objects, user interfaces, validation, persistence, navigation, and business operations. Apache Causeway takes a different approach by allowing developers to focus primarily on the domain model while the framework automatically provides much of the application UI and supporting infrastructure. Apache Causeway is an open-source framework for building domain-driven applications in Java. Instead of manually creating every screen and controller, developers define domain classes and expose their behavior through methods. Causeway can then derive a user interface from that domain model. This makes Causeway particularly interesting for applications where the domain model is the primary focus and where a conventional enterprise CRUD-style interface is sufficient.
1. Understanding Apache Causeway
The central idea behind Apache Causeway is that the domain model drives the application. Developers define entities and business operations using regular Java classes, and Causeway inspects these classes to derive the application’s interface from the exposed domain behavior. For example, in a customer management application, instead of creating separate controllers, service endpoints, and UI pages for individual operations, a developer can define a Customer domain object with business methods such as changeName() or deactivate(). Causeway can then expose these methods as actions in its generated UI. Conceptually, the flow is Java Domain Objects → Apache Causeway → Generated UI + Persistence/Services. This approach aligns closely with domain-driven design, where domain objects encapsulate meaningful business behavior rather than simply acting as containers for data.
1.1 Core Concepts of Apache Causeway
- Domain objects: Java classes representing business concepts.
- Properties: Fields or accessor methods representing object state.
- Actions: Business operations exposed through methods.
- Repositories: Components responsible for finding and managing domain objects.
- Conventions: Causeway uses Java conventions and annotations to understand the domain model.
1.2 Apache Causeway vs. Traditional MVC
| Traditional MVC | Apache Causeway |
|---|---|
| Developers manually create controllers and UI screens. | The framework derives much of the UI from the domain model. |
| Business operations are often exposed through controllers or REST endpoints. | Business operations can be exposed directly as domain actions. |
| Navigation and UI behavior are explicitly implemented. | Navigation and interactions can be derived from the domain model. |
| More application-layer boilerplate is typically required. | Less boilerplate is required for domain-centric applications. |
| The UI and domain model are often developed as separate layers. | The domain model is the primary driver of the application. |
1.3 When Should You Use Apache Causeway?
Apache Causeway is particularly suitable for applications where the business domain is complex and users interact directly with domain objects and their operations. It can be a good choice for internal enterprise systems, administrative applications, back-office applications, and CRUD-oriented business systems where a generated interface is sufficient. Typical use cases include:
- Enterprise administration and management applications.
- Back-office systems used by employees and operations teams.
- Business applications centered around domain entities and workflows.
- Internal CRUD applications where rapid development is important.
- Applications where business rules and domain behavior are more important than highly customized visual design.
Apache Causeway may be less suitable when the application requires a highly customized consumer-facing experience, pixel-perfect UI design, complex frontend interactions, or a completely independent frontend architecture. In such scenarios, a traditional Spring Boot backend combined with React, Angular, or another dedicated frontend framework may provide greater flexibility. The key question is whether the application can be naturally modeled around domain objects and their behavior. If the answer is yes, Apache Causeway can significantly reduce the amount of UI and infrastructure code that needs to be written manually.
1.4 Advantages
- Reduced boilerplate: Developers can avoid manually implementing many controllers, screens, and navigation elements.
- Domain-centric development: Business behavior remains close to the domain objects that own that behavior.
- Rapid application development: A functional application can be created quickly from a well-defined domain model.
- Automatic UI generation: The framework can generate much of the application interface from domain metadata and exposed behavior.
- Consistency: Common UI patterns and interactions are handled by the framework instead of being implemented repeatedly.
- Easier evolution: Changes to the domain model can automatically influence the generated application interface.
1.5 Limitations
- UI customization: Highly specialized or pixel-perfect user interfaces may be easier to build with a dedicated frontend framework.
- Framework learning curve: Developers need to understand Causeway’s conventions, annotations, lifecycle, and domain modeling approach.
- Domain-model dependency: Applications that do not naturally fit a domain-centric model may not benefit as much from Causeway.
- Framework coupling: The application relies on Causeway-specific concepts and conventions, which should be considered when evaluating long-term architecture.
- Consumer-facing applications: Applications where visual experience and highly interactive frontend behavior are primary requirements may be better served by a conventional frontend architecture.
Overall, Apache Causeway is most valuable when the domain model is the natural center of the application. It allows developers to spend more time defining business concepts and behavior and less time implementing repetitive application infrastructure.
2. Building a Domain-Driven Application with Apache Causeway
2.1 Configuring Maven Dependencies
The following Maven dependencies provide the basic Apache Causeway and Spring Boot setup required to run the application:
<dependencies>
<dependency>
<groupId>org.apache.causeway.core</groupId>
<artifactId>causeway-boot-starter-webapp</artifactId>
<version>stable__jar__version</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
The causeway-boot-starter-webapp dependency provides the core Causeway runtime and web application support. Spring Boot is used to bootstrap the application.
2.2 Defining the Customer Domain Object
The Customer class represents a domain object in the application. It contains the customer’s name and exposes a changeName() business action that can be discovered and presented by Apache Causeway.
package com.example.demo.dom;
import org.apache.causeway.applib.annotation.Action;
import org.apache.causeway.applib.annotation.DomainObject;
import org.apache.causeway.applib.annotation.Property;
@DomainObject
public class Customer {
@Property
private String name;
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Action
public Customer changeName(String newName) {
if (newName == null || newName.isBlank()) {
throw new IllegalArgumentException("Name cannot be empty");
}
this.name = newName;
return this;
}
@Override
public String toString() {
return "Customer{name='" + name + "'}";
}
}
The @DomainObject annotation identifies Customer as a Causeway domain object, while @Property exposes the name property. The changeName() method is annotated with @Action, allowing Causeway to expose it as an operation in the generated UI. The method also validates the new name before updating the object, and the toString() method provides a simple textual representation of the customer.
2.3 Creating the Customer Repository
The CustomerRepository class provides simple operations for creating and finding Customer objects. It is registered as a Causeway domain service and initializes the application with two sample customers.
package com.example.demo.dom;
import java.util.ArrayList;
import java.util.List;
import org.apache.causeway.applib.annotation.DomainService;
import org.apache.causeway.applib.annotation.NatureOfService;
@DomainService(
nature = NatureOfService.VIEW_MENU,
logicalTypeName = "customer.CustomerRepository")
public class CustomerRepository {
private final List<Customer> customers = new ArrayList<>();
public CustomerRepository() {
customers.add(new Customer("John"));
customers.add(new Customer("Alice"));
}
public List<Customer> findAll() {
return customers;
}
public Customer findByName(String name) {
return customers.stream()
.filter(customer ->
customer.getName().equalsIgnoreCase(name))
.findFirst()
.orElse(null);
}
}
The @DomainService annotation registers the class as a Causeway domain service and makes it available through the application’s domain model. The constructor creates two sample Customer objects, while findAll() returns all customers and findByName() searches for a customer by name using a case-insensitive comparison. In a production application, this repository could instead retrieve customers from a database.
2.4 Creating the Spring Boot Application
The Application class is the entry point of the application. It uses Spring Boot to initialize the application context and start the Apache Causeway application.
package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
The @SpringBootApplication annotation enables Spring Boot’s auto-configuration and component scanning, allowing the application to discover the Causeway domain objects and services. The main() method calls SpringApplication.run() to start the application and initialize the required framework components.
2.5 Running the Application and Understanding the Output
After adding the dependencies and Java classes, start the application using Maven: mvn spring-boot:run. Once the application starts successfully, Causeway discovers the Customer domain object and its exposed behavior. The repository provides the initial customers, while the changeName() method is exposed as an action that can be invoked from the generated UI. For example, the application starts with the following customers:
Customer{name='John'}
Customer{name='Alice'}

If the changeName() action is invoked for John with Jonathan as the new name, the resulting domain object is:
Before:
Customer{name='John'}
Action:
changeName("Jonathan")
After:
Customer{name='Jonathan'}
This demonstrates the main benefit of Apache Causeway: the application behavior is derived from the domain model, so the developer can focus on defining domain objects and their business operations instead of manually creating separate controllers and UI screens for each operation.
3. Conclusion
Apache Causeway provides a domain-driven approach to building Java applications. Instead of treating the UI, controllers, and domain model as completely separate concerns, Causeway allows developers to define the domain model and derive much of the application interface from it. The key idea is simple: define meaningful domain objects and their behavior, and let the framework provide much of the surrounding application infrastructure. This can make enterprise applications faster to develop and easier to evolve when the domain model is the primary driver of the application’s functionality.




