Skip to main content

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.


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

CustomUserContext is 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
  • 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