TeaQL Best Practices in Spring Boot / Spring Cloud
This document summarizes recommended usage patterns and best practices for TeaQL in Spring Boot / Spring Cloud projects. It is intended to help teams build clean layering, strong testability, and long-term maintainability.
1. Recommended Call Flow
In Spring Boot / Spring Cloud projects, the recommended invocation chain is:
Controller -> Service -> Util
Design Goals
- Controller: protocol adaptation only (HTTP / RPC)
- Service: transaction boundaries and business orchestration
- Util: reusable, testable, pure business logic
2. Unified Context: CustomUserContext
CustomUserContextis a project-specific context class.
Why it matters
- Centralizes user, permission, tenant, and request metadata
- Enables shared common methods across layers
- Prevents excessive parameter passing
3. Controller Layer Practices
Example
@GetMapping("/info")
public Object info(@TQLContext CustomUserContext userContext) {
return service.info(userContext);
}
Best Practices
- The first parameter in Controller methods should be annotated with
@TQLContext - Keep Controllers minimal:
- No business logic
- No complex condition handling
- No transaction management
- Controllers should only:
- Accept request parameters
- Delegate to Service
- Return results
4. Service Layer Practices
Example
public Object info(@TQLContext CustomUserContext userContext, OtherParam param) {
return InfoUtil.info(userContext, param);
}
Best Practices
- Service layer responsibilities:
- Define transaction boundaries (e.g.
@Transactional) - Orchestrate business flows
- Define transaction boundaries (e.g.
- Inside Service methods:
- Keep logic concise
- Avoid complex TeaQL expressions
- Delegate heavy logic to Util layer
5. Util Layer Practices
Example
public class InfoUtil {
public static Object info(@TQLContext CustomUserContext userContext, OtherParam param) {
return Q.orders()
.whichUserId(userContext.getUserId())
.executeForList(userContext);
}
}
Best Practices
- Prefer static methods
- Decouple from Spring Beans and lifecycle
- Key benefits:
- Easier unit testing
- Better reusability
- Clearer composition across Services
6. General TeaQL Best Practices
6.1 Minimize RawSQL Usage
- Avoid using RawSQL whenever possible
- Prefer:
- Semantic TeaQL expressions
- Composable query fragments
6.2 Avoid DTO Explosion
- Do not create large numbers of scenario-specific DTOs
- Recommended approach:
- Extend generated Entity Classes
- Add business logic in subclasses
6.3 Entity Classes as DDD Aggregate Roots
- Extend Entity Classes
- Add business behaviors directly to entities
- Use them as Aggregate Roots in DDD design
6.4 Dynamic Properties
TeaQL supports dynamic properties:
bean.setDynamicProperty("name", value);
- After JSON serialization, the field appears as:
_name
- Suitable for:
- Temporary frontend fields
- Non-persistent computed values
6.5 Query Fragment Reuse
TeaQL allows reusable query fragments via static methods:
public static OrderRequest shippedOrders() {
return Q.orders().whichStatusAreShipped();
}
Further composition:
shippedOrders().filterByUserId(userId);
Benefits:
- Unified business semantics
- Reduced duplication
- Improved readability
6.6 Readability in Complex Scenarios
- TeaQL supports deeply nested queries
- For complex business scenarios:
- Use semantic Request wrappers
- Let method names express business intent
This significantly improves:
- Code readability
- Maintainability in complex domains
7. Summary
By following these practices:
- TeaQL queries remain clear and centralized
- Spring Boot / Cloud layering stays stable
- Code becomes easier to test and evolve
Recommended for:
- Medium to large Spring Cloud projects
- Systems where TeaQL is the core data access and business expression layer