어노테이션과 메서드
규칙이 생성 코드에 하는 일의 대부분은 "어디에 무엇을 붙이거나 뺀다" 입니다. 모두 ctx(spec) 이 돌려주는 지금 만드는
파일(SourceCode)에 말합니다. import 정리, 줄 배치, Java/Kotlin 문법은 생성기가 합니다.
어디에
| 어디에 | 붙이기 | 빼기 |
|---|---|---|
| 클래스 | ctx(e).ensureClassAnnotation(anno) | ctx(e).removeClassAnnotation("a.b.C") |
| 필드 | ctx(e).field(f).ensure(anno) | ctx(e).field(f).removeAnnotation("a.b.C") |
| 메서드 (이름으로) | ctx(e).method("name").ensure(anno) | - |
| 필드 자체 | - | ctx(e).removeField(f) |
| 파일 자체 | - | ctx(e).dontMake() |
빼는 쪽은 기본 규칙이 붙인 것도 뺍니다. 팀 규칙은 항상 기본 규칙 뒤에 돌기 때문입니다.
/** Takes the @DynamicUpdate the built-in rules put on every entity back off. */
@Rule("ps-no-dynamic-update")
void noDynamicUpdate(EntitySpec e) {
ctx(e).removeClassAnnotation("org.hibernate.annotations.DynamicUpdate");
}
펫스토어에서 이 규칙은 생성기 파일(Customer.java, PurchaseOrderBase.java …)뿐 아니라 나뉜 루트의 개발자 클래스
(PurchaseOrder.java, OrderLine.java)에서도 @DynamicUpdate 를 뺐습니다. 생성기는 개발자 클래스의 테이블 어노테이션
(@Entity, @Table, @DynamicUpdate …)을 계속 DSL 에 맞추고, 본문과 개발자가 붙인 다른 어노테이션은 그대로 둡니다.
필드: ensure, add, merge, replace
| 메서드 | 같은 어노테이션이 이미 있으면 | 없으면 | 언제 |
|---|---|---|---|
ensure(anno) | 아무것도 안 함 | 붙임 | 대부분 |
add(anno) | 하나 더 붙임 | 붙임 | 반복 가능한 어노테이션 |
merge(anno) | 속성만 더함 | 붙임 | 기본 규칙이 붙인 @Schema, @Column 에 속성 하나 더하기 |
replace(anno) | 이것으로 바꿈 | 붙임 | 기본 규칙의 값을 팀 값으로 |
DTO 필드에는 ElastiCORE 가 이미 @Schema(description = ...) 를 붙이므로, hidden = true 를 더하려면 merge 입니다.
ensure 로 쓰면 아무 일도 일어나지 않습니다 - 대상 파일의 예.
/** A field marked @pii in the DSL is accepted in requests but never sent back in responses. */
@Rule(value = "ps-pii", target = "dto")
void pii(EntitySpec dto, FieldSpec f) {
if (f.hasDsl("pii")) {
ctx(dto).field(f).ensure(AnnoCode.of("com.fasterxml.jackson.annotation.JsonProperty")
.valRaw("access", "JsonProperty.Access.WRITE_ONLY"));
}
}
CustomerDTO.java
@Schema(description = "email address" )
@Size(max=100)
@Email(message = "Email format invalid")
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY) // ps-pii
private String email;
실행해서 확인: 회원 가입(POST /api/petstore/customer)에 email 을 보내면 저장되고, 응답 JSON 에는 email 이 없습니다.
{"customerId":3,"firstName":"Rule","homeAddress":{…},"lastName":"Demo","login":"rulesdemo3","role":"U"}