An IntelliJ IDEA plugin that enforces architectural layering rules in Java projects using Maven build system.
The plugin enforces the following layering rules:
- Purpose: Handle HTTP requests/responses
- Rules:
- Should have no business logic
- Should only call DTO layer
- Naming conventions: Classes ending with
Controller,Resource,Endpointor in packages containingcontroller,web,rest
- Purpose: Data validation, conversion, and transfer
- Rules:
- Should only call API layer
- Should do validations and conversions
- Should have no business logic
- Naming conventions: Classes ending with
DTO,Dto,Request,Response,Modelor in packages containingdto,model
- Purpose: Contains all business logic
- Rules:
- Should contain business logic
- Should call DAO or FLOW layers
- Should not call other API layers directly
- Naming conventions: Classes ending with
Service,ServiceImpl,Manager,Handler,Processoror in packages containingservice,business,logic
- Purpose: Orchestrate multiple API calls
- Rules:
- Should be used when API needs to call other APIs
- Should orchestrate API operations
- Should call API layers only
- Naming conventions: Classes ending with
Flow,Workflow,Orchestrator,Coordinatoror in packages containingflow,workflow,orchestrat
- Purpose: Database interaction
- Rules:
- Should only talk to database
- Should contain no business logic
- Should handle data persistence operations
- Naming conventions: Classes ending with
DAO,Dao,Repository,Mapper,Entityor in packages containingdao,repository,data,persistence
-
Download the latest plugin:
- Go to Releases
- Download
layer-dog-x.x.x.zipfrom the latest release
-
Install in IntelliJ IDEA:
- Go to
File → Settings → Plugins - Click the ⚙️ gear icon and select
Install Plugin from Disk... - Select the downloaded ZIP file
- Restart IntelliJ IDEA
- Go to
- Clone this repository
- Open in IntelliJ IDEA
- Run the Gradle task:
./gradlew buildPlugin - The plugin will be built in
build/distributions/
Once installed, the plugin automatically checks your Java code for layer violations:
- Violations are highlighted with red underlines as you type
- Error messages explain the specific violation
- Hover over violations to see detailed descriptions
Each violation includes quick fixes that provide guidance on how to resolve the issue:
- Move to DTO Layer: For controller violations
- Use FLOW Layer: For API-to-API communication
- Extract Business Logic: For logic in wrong layers
- Create DAO Method: For data access violations
The plugin works out of the box with default naming conventions. It detects layers based on:
- Class name suffixes (Controller, DTO, Service, Flow, DAO, etc.)
- Package names (controller, dto, service, flow, dao, etc.)
- Annotations (@Controller, @Service, @Repository, etc.)
// Controller - only calls DTO
@RestController
public class UserController {
private UserDTO userDTO;
public ResponseEntity<User> getUser(Long id) {
return ResponseEntity.ok(userDTO.getUser(id));
}
}
// DTO - calls API layer
public class UserDTO {
private UserService userService;
public User getUser(Long id) {
// Validation and conversion
validateId(id);
return userService.findUser(id);
}
}
// API/Service - contains business logic
@Service
public class UserService {
private UserDAO userDAO;
private UserFlow userFlow; // For complex operations
public User findUser(Long id) {
// Business logic here
return userDAO.findById(id);
}
}
// FLOW - orchestrates multiple APIs
public class UserFlow {
private UserService userService;
private NotificationService notificationService;
public void processUserRegistration(User user) {
userService.createUser(user);
notificationService.sendWelcomeEmail(user);
}
}
// DAO - database operations only
@Repository
public class UserDAO {
public User findById(Long id) {
// Database query
return entityManager.find(User.class, id);
}
}// ❌ Controller calling API directly
@RestController
public class UserController {
private UserService userService; // Should use DTO instead
}
// ❌ DTO with business logic
public class UserDTO {
public User processUser(User user) {
// ❌ Complex business logic should be in API layer
if (user.getAge() > 65) {
user.setDiscount(0.15);
calculatePremium(user);
}
return user;
}
}
// ❌ API calling another API directly
@Service
public class UserService {
private OrderService orderService; // ❌ Should use FLOW layer
}
// ❌ DAO with business logic
@Repository
public class UserDAO {
public User findUser(Long id) {
User user = findById(id);
// ❌ Business logic should be in API layer
if (user.isActive()) {
user.updateLastAccessed();
}
return user;
}
}The plugin recognizes these common annotations for layer detection:
@RestController,@Controller→ Controller layer@Service→ API layer@Repository,@Entity,@Table→ DAO layer
src/main/kotlin/com/layerdog/
├── inspections/ # Inspection implementations
│ ├── BaseLayerInspection.kt
│ ├── ControllerLayerInspection.kt
│ ├── DTOLayerInspection.kt
│ ├── APILayerInspection.kt
│ ├── FlowLayerInspection.kt
│ └── DAOLayerInspection.kt
└── utils/
└── LayerDetector.kt # Layer detection utility
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Submit a pull request
This project is licensed under the MIT License.
For issues and feature requests, please create an issue in the GitHub repository.