env.yml 설정
도메인 폴더 src/main/resources/blueprint/<도메인>/ 마다 env.yml 이 있습니다.
blueprint/petstore/env.yml (Pet Store)
elasticore:
enable: true
config:
domainName: petstore
framework: springboot
mode: jpa
j2ee: jakarta
apiPath: "/api" # REST 주소는 /api/petstore/...
table:
prefix: ps_
referenceColumn: short # 다른 애그리거트 참조 컬럼: category_id (기본은 2.x 식 category_category_id)
annotations:
genid: "genid(io.elasticore.springboot3.util.IdUtils.newId)"
namespace:
base: io.elasticore.sample.petstore
config:
| 키 | 뜻 |
|---|---|
domainName | 도메인 이름 - 패키지, 파일 이름, API 경로에 씀 |
framework, mode, j2ee | springboot, jpa(그 밖에 mongo, uml, dsl - 쉼표로 여러 개), jakarta |
apiPath | REST 경로의 시작 (기본 /api): /api/v1 이면 /api/v1/<도메인>/<엔티티> |
table.prefix | 테이블 이름 접두사 (ps_ 면 ps_purchase_order) |
table.autoJoin | true: findById 에서 모든 참조를 JOIN FETCH (아니면 @fetchjoin 필드만) |
tableSchema | 모든 테이블의 DB 스키마 (엔티티의 @schema 가 우선) |
annotations | @env:이름 필드가 쓰는 어노테이션, genid 생성기 |
testCode: "true" | JUnit 5 + Mockito 서비스 테스트 |
supportAI: "true" | 확장 서비스에 Spring AI @Tool 메서드 (Spring Boot) |
jsonview | false(기본), true, auto - Jackson @JsonView 가시성 |
publisher.rules, publisher.suppress | 이 도메인의 규칙 번들, 끌 규칙 (규칙 엔진) |
springBoot: 4 | 플러그인 없이 생성할 때의 Boot 버전 |
httpPort: spring | HTTP 포트를 Spring @HttpExchange 클라이언트로 (Boot 4) (HTTP 포트) |
context | 바운디드 컨텍스트의 경계 (아래) |
referenceColumn: short | DDD ID 참조의 컬럼 이름을 필드 이름으로(customer_id) - 기존 컬럼 이름이 바뀌므로 새 프로젝트용 |
adminRole | @access(admin) 이 확인하는 역할 (기본 ADMIN) |
outbox: true | 도메인 이벤트를 트랜잭션 outbox 로 (이벤트) |
mapping: xml | JPA 매핑을 META-INF/orm.xml 로, 도메인 클래스에 jakarta.persistence 없음 |
archTest: true | ArchUnit <Domain>ArchitectureTest 를 한 번 생성 (com.tngtech.archunit:archunit-junit5:1.3.0 필요) |
namespace:
base 는 헥사고날 패키지를 한 패키지 아래에 깔고, 함께 적은 키가 우선합니다:
| 키 | base: com.acme.erp 일 때 패키지 |
|---|---|
entity, enumeration | com.acme.erp.domain.model |
event / domainService / domainRepository | .domain.event / .domain.service / .domain.repository |
service / dto | .application / .application.dto |
inboundPort / queryPort, port | .application.port.in / .application.port.out |
control | .adapter.in.web |
repository, persistence | .infrastructure.persistence |
레이어드·DDD·헥사고날 프리셋: 아키텍처.
멀티 모듈
멀티 모듈 빌드에서는 네임스페이스가 모듈명://패키지 로 다른 모듈을 가리킬 수 있습니다. 예를 들어 서비스·컨트롤러만
애플리케이션 모듈에 생성하려면:
namespace:
service: app-admin://com.acme.shop.service
루트에 적용한 플러그인은 src/main/resources/blueprint 를 가진 하위 모듈을 모두 찾습니다(직접 정하려면
elasticore { modules = ['core-domain', 'app-admin'] }).
바운디드 컨텍스트
blueprint 도메인 하나가 바운디드 컨텍스트 하나입니다. context: 를 적은 도메인은 다른 컨텍스트에서 무엇을 가져다
쓰는지(uses)와 다른 컨텍스트가 무엇을 써도 되는지(publishes)를 선언하고, 빌드가 그 경계를 지킵니다.
# blueprint/catalog/env.yml
config:
context:
publishes: [ProductDTO, Unit] # 다른 컨텍스트가 필드 타입으로 써도 되는 것 (DTO, enum, @embeddable)
# blueprint/shop/env.yml
config:
context:
uses: catalog # 이 컨텍스트가 기대는 상위 컨텍스트들
publishes: [OrderPlaced] # 이벤트도 내보낼 수 있음 (루트 이름 + 이벤트 이름)
| 상황 | 결과 |
|---|---|
shop 의 필드가 catalog 의 ProductDTO 를 씀 (양쪽에 있음) | 통과 |
shop 의 필드가 catalog 의 엔티티 Product 를 씀 | 빌드 실패: 다른 컨텍스트의 엔티티는 필드 타입이 될 수 없음 - 식별자(productId: long)만 들거나 내보내는 DTO 를 씀 |
uses 에 없는 컨텍스트의 타입 | 빌드 실패 (... does not declare it (config.context.uses: catalog)) |
상대가 선언한 publishes 에 없는 타입 | 빌드 실패 (... which catalog does not publish) |
다른 컨텍스트의 프로세스 매니저가 on: [shop:OrderPlaced] | 타입과 같은 검사 |
어느 쪽도 context: 가 없음 | 예전과 같음 |
[elcore3] context: [shop] Order.product is catalog's entity Product: another context's entity is no field type
- hold its id (productId: long), or use a DTO catalog publishes.
어느 도메인이든 context: 를 적으면 blueprint/context-map.md(Mermaid 컨텍스트 지도, GitHub 에서 그대로 보임)도
생깁니다. 2.x 생성기는 context: 를 읽지 않습니다.
도메인 하나만 생성
./gradlew elcore3 -Pdomain=shop
모든 도메인을 읽은 뒤(도메인을 넘는 참조가 풀리도록) shop 만 씁니다. DSL 이 더는 만들지 않는 파일의 정리는 모든
도메인을 생성한 실행에서만 합니다.