RAP Validation — on MODIFY vs on SAVE, 언제 실행되는지 혼동 끝내기
SAP RAP(RESTful Application Programming)에서 비즈니스 데이터의 무결성을 지키는 핵심 메커니즘이 바로 Validation입니다. 그런데 수많은 RAP 개발자들이 실제 프로젝트에서 동일한 질문을 반복합니다. "이 Validation은 저장 버튼을 눌렀을 때 실행되는 건가요, 아니면 필드를 바꾸는 순간 실행되는 건가요?" 이 글에서는 on MODIFY와 on SAVE의 트리거 타이밍을 코드 예제와 함께 완전히 구분하겠습니다.
RAP Validation이란 무엇인가
RAP에서 Validation은 Behavior Definition(BDEF)에 선언하고 Behavior Implementation(BIL) 클래스에 구현하는 비즈니스 규칙 검증 로직입니다. 사용자가 입력한 데이터가 허용 범위 내에 있는지, 필수 필드가 채워져 있는지, 조합 조건이 충족되는지를 런타임에서 검사합니다.
Validation은 크게 두 가지 타이밍에 동작합니다.
첫 번째는 on MODIFY입니다. 특정 필드의 값이 변경되는 순간, 즉 사용자가 입력을 마치고 포커스를 이동하거나 다른 필드를 탭하는 시점에 트리거됩니다. 주로 필드 수준의 즉각적인 피드백이 필요할 때 사용합니다.
두 번째는 on SAVE입니다. 사용자가 Save 버튼을 클릭하거나 애플리케이션이 저장 시퀀스를 시작할 때 실행됩니다. 모든 필드 입력이 완료된 후 엔티티 전체를 대상으로 검증이 필요할 때 적합합니다.
on MODIFY Validation — 필드 변경 즉시 반응
on MODIFY는 특정 필드가 변경되었을 때 바로 동작하는 Validation입니다. BDEF에서 다음과 같이 선언합니다.
define behavior for ZI_SalesOrder alias SalesOrder
...
{
validation validateNetAmount on MODIFY field NetAmount;
validation validateCurrency on MODIFY field CurrencyCode;
}
위 선언에서 field NetAmount는 NetAmount 필드가 바뀔 때마다 validateNetAmount가 호출된다는 의미입니다. 구현 클래스에서는 아래처럼 작성합니다.
METHOD validateNetAmount.
READ ENTITIES OF zi_salesorder IN LOCAL MODE
ENTITY SalesOrder
FIELDS ( NetAmount )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_orders).
LOOP AT lt_orders INTO DATA(ls_order).
IF ls_order-NetAmount IS INITIAL OR ls_order-NetAmount <= 0.
APPEND VALUE #( %tky = ls_order-%tky ) TO failed-salesorder.
APPEND VALUE #(
%tky = ls_order-%tky
%msg = new_message(
id = 'ZSO_MSG'
number = '001'
severity = if_abap_behv_message=>severity-error
v1 = ls_order-NetAmount
)
) TO reported-salesorder.
ENDIF.
ENDLOOP.
ENDMETHOD.
on MODIFY Validation은 UI에서 즉각적인 오류 메시지를 표시하여 사용자 경험을 향상시킵니다. 단, 이 시점은 아직 DB에 저장되기 전이므로 커밋 완료 데이터 기반 비교 검사에는 적합하지 않습니다.
on SAVE Validation — 저장 직전 최종 관문
on SAVE는 Save 시퀀스가 시작되는 시점에 실행됩니다. 사용자가 모든 필드를 입력한 후 저장을 시도할 때 한 번에 모든 규칙을 검사하는 방식입니다. BDEF 선언은 다음과 같습니다.
define behavior for ZI_SalesOrder alias SalesOrder
...
{
validation validateOrderComplete on SAVE;
validation validateApprovalStatus on SAVE;
}
필드 키워드 없이 on SAVE만 선언하면 어떤 필드가 변경되든 Save 시점에 항상 실행됩니다. 구현 예제입니다.
METHOD validateOrderComplete.
READ ENTITIES OF zi_salesorder IN LOCAL MODE
ENTITY SalesOrder
FIELDS ( OrderStatus CustomerID DeliveryDate )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_orders)
FAILED DATA(lt_failed_orders).
LOOP AT lt_orders INTO DATA(ls_order).
" 필수 고객 정보 검사
IF ls_order-CustomerID IS INITIAL.
APPEND VALUE #( %tky = ls_order-%tky ) TO failed-salesorder.
APPEND VALUE #(
%tky = ls_order-%tky
%msg = new_message(
id = 'ZSO_MSG'
number = '010'
severity = if_abap_behv_message=>severity-error
)
) TO reported-salesorder.
ENDIF.
" 납기일이 오늘 이전인지 검사
IF ls_order-DeliveryDate < cl_abap_context_info=>get_system_date( ).
APPEND VALUE #( %tky = ls_order-%tky ) TO failed-salesorder.
APPEND VALUE #(
%tky = ls_order-%tky
%msg = new_message(
id = 'ZSO_MSG'
number = '011'
severity = if_abap_behv_message=>severity-error
)
) TO reported-salesorder.
ENDIF.
ENDLOOP.
ENDMETHOD.
on SAVE Validation은 저장 직전에 실행되므로, 트랜잭션 내의 모든 변경 사항이 반영된 상태에서 검증할 수 있다는 장점이 있습니다. 여러 필드 간의 복합 조건 검사, 외부 API 결과와의 비교, 엔티티 상태 전이 규칙 등을 이 시점에 배치하는 것이 좋습니다.
on MODIFY vs on SAVE — 핵심 차이점 비교
두 타이밍의 가장 큰 차이는 실행 시점과 목적입니다.
실행 시점
- on MODIFY: 특정 필드 값이 변경되는 즉시
- on SAVE: Save 시퀀스가 시작될 때 (모든 변경 완료 후)
적합한 검증 유형
- on MODIFY: 개별 필드 형식 검사, 범위 검사, 단일 필드 필수값 체크
- on SAVE: 복합 필드 조합 규칙, 엔티티 완결성 검사, 외부 시스템 연동 검증
성능 고려사항
- on MODIFY: 사용자가 필드를 수정할 때마다 호출되므로, 무거운 DB 조회나 외부 API 호출은 피해야 합니다
- on SAVE: 저장 시 한 번만 실행되므로, 복잡한 비즈니스 로직이나 DB 집약적 검증에 적합합니다
UX 영향
- on MODIFY: 실시간 피드백으로 사용자가 오류를 즉시 인지
- on SAVE: 저장 버튼 클릭 후 오류 목록 일괄 표시
on SAVE에 특정 필드 조건 추가하기
on SAVE에도 필드 트리거를 결합할 수 있습니다. 이 경우 해당 필드가 변경된 인스턴스가 있을 때만 Save 시점에 Validation이 호출됩니다.
define behavior for ZI_PurchaseRequisition alias PurchReq
...
{
validation validateBudgetLimit on SAVE field TotalCost, CostCenter;
}
위 선언은 TotalCost 또는 CostCenter 필드가 변경된 인스턴스에 한해 Save 시 validateBudgetLimit이 실행됩니다. 변경이 없는 인스턴스는 건너뛰어 성능을 최적화할 수 있습니다.
METHOD validateBudgetLimit.
READ ENTITIES OF zi_purchreq IN LOCAL MODE
ENTITY PurchReq
FIELDS ( TotalCost CostCenter ApprovalStatus )
WITH CORRESPONDING #( keys )
RESULT DATA(lt_reqs).
" 비용 센터별 예산 한도 조회 (간략화 예제)
SELECT costcenter, budgetlimit
FROM zbdgt_limit
INTO TABLE @DATA(lt_budgets)
FOR ALL ENTRIES IN @lt_reqs
WHERE costcenter = @lt_reqs-CostCenter.
LOOP AT lt_reqs INTO DATA(ls_req).
READ TABLE lt_budgets INTO DATA(ls_budget)
WITH KEY costcenter = ls_req-CostCenter.
IF sy-subrc = 0 AND ls_req-TotalCost > ls_budget-budgetlimit.
APPEND VALUE #( %tky = ls_req-%tky ) TO failed-purchreq.
APPEND VALUE #(
%tky = ls_req-%tky
%msg = new_message(
id = 'ZPURR_MSG'
number = '020'
severity = if_abap_behv_message=>severity-error
v1 = ls_req-CostCenter
v2 = ls_budget-budgetlimit
)
) TO reported-purchreq.
ENDIF.
ENDLOOP.
ENDMETHOD.
Draft 시나리오에서의 Validation 동작
Draft-enabled RAP 오브젝트에서는 Validation 타이밍이 더욱 중요해집니다. Draft 상태에서 on MODIFY Validation은 Draft 테이블에 대한 변경 시 동작하며, on SAVE는 Draft를 활성화(Activate)하거나 직접 Save하는 시점에 실행됩니다.
define behavior for ZI_LeaveRequest alias LeaveReq
...
with draft;
{
draft action Activate optimized;
validation validateDateRange on MODIFY field StartDate, EndDate;
validation validateLeaveBalance on SAVE;
}
validateDateRange는 Draft 편집 중 StartDate나 EndDate가 바뀔 때마다 호출됩니다. validateLeaveBalance는 Draft Activate 시점에 실행됩니다. 이 구분을 무시하면 Draft 상태에서 오류가 전혀 나타나지 않거나 불필요한 성능 저하가 발생합니다.
실전에서 자주 발생하는 실수 3가지
첫 번째 실수는 on MODIFY에 무거운 SELECT를 넣는 것입니다. 사용자가 필드를 바꿀 때마다 대용량 DB 조회가 실행되면 UI가 느려지고 서버 부하가 급증합니다. 필드 수준 형식 검사나 가벼운 도메인 값 체크는 on MODIFY에, 복잡한 DB 조회는 on SAVE에 배치하세요.
두 번째 실수는 on SAVE에서만 필수 필드를 검사하는 것입니다. 필수 필드를 빠뜨렸을 때 Save 시점에야 오류가 나오면 UX가 나빠집니다. 단일 필드 필수값은 on MODIFY로 즉시 피드백을 주세요.
세 번째 실수는 Draft와 Active 오브젝트의 타이밍을 혼동하는 것입니다. Draft Activate는 on SAVE를 트리거하지만, Draft 자동 저장은 on SAVE를 트리거하지 않습니다. 이 차이를 테스트로 반드시 확인하세요.
언제 어떤 Validation을 쓸지 — 결정 기준
다음 질문에 답하면 타이밍 선택이 명확해집니다.
- 이 검증이 단일 필드 값만 보면 되는가? → on MODIFY
- 다른 필드 값과 조합해서 판단해야 하는가? → on SAVE
- 사용자에게 즉각적인 피드백이 필요한가? → on MODIFY
- 외부 시스템(RFC, HTTP 서비스)을 호출해야 하는가? → on SAVE
- Draft Activate 시점에만 검증이 의미 있는가? → on SAVE
- 특정 필드가 변경된 인스턴스만 선별해서 Save 시 검증하고 싶은가? → on SAVE field 조합 사용
정리 — on MODIFY vs on SAVE 한 줄 요약
on MODIFY는 "필드 바뀌는 그 순간" 즉시 반응하는 실시간 검증이고, on SAVE는 "저장 버튼 눌렀을 때" 전체를 한 번에 점검하는 최종 관문입니다. 두 타이밍을 용도에 맞게 혼합해서 사용하면 빠른 사용자 피드백과 안정적인 데이터 무결성을 동시에 달성할 수 있습니다. 오늘부터 Validation 선언 전에 "이게 필드 변경 즉시인가, 저장 시점인가"를 먼저 확인하는 습관을 들이세요.
댓글 0
아직 댓글이 없습니다.