TL;DR — 5분 안에 알아둘 것
SAP RAP(RESTful Application Programming Model)의 Managed 시나리오에서 Business Object의 실질적인 비즈니스 로직은 Validation, Determination, Action 세 가지 메커니즘으로 구현됩니다. 이 글은 RAP의 4-Layer 구조(입문편에서 다룬 내용)를 이미 이해한 개발자를 대상으로, Behavior Definition(BDEF)에서 이 세 가지를 선언하고 Behavior Implementation Class에서 실제 로직을 작성하는 전 과정을 다룹니다.
- Validation으로 저장 시점 데이터 검증 로직을 구현할 수 있다
- Determination으로 레코드 생성/수정 시 자동 필드 설정을 구현할 수 있다
- Instance Action과 Factory Action의 차이를 이해하고 각각 구현할 수 있다
- Draft 시나리오에서 Prepare Action과 Validation의 연동 구조를 설명할 수 있다
- failed/reported 구조체를 활용한 오류 처리 패턴을 적용할 수 있다
사전 가정
- ABAP 기본 문법 (클래스, 메서드, 인터널 테이블)
- RAP Business Object의 4-Layer 구조 이해 (Data Model → Service Definition → Service Binding → Behavior Definition)
- CDS View Entity 기본 개념
- ADT(ABAP Development Tools) 사용 경험
RAP 4-Layer 구조가 낯선 경우, 입문편("[RAP] ABAP RESTful Application Programming Model 입문 — Business Object 4-Layer 구조 완전 가이드")을 먼저 참고하시기 바랍니다.
테스트 환경
| 항목권장 사양 | |
| SAP BTP ABAP Environment | 2022 이상 (또는 S/4HANA 2021 이상) |
| ADT (Eclipse) | 최신 버전 권장 |
| ABAP Language Version | ABAP for Cloud Development |
| 참고 워크숍 | SAP RAP100 (openSAP / SAP-samples) |
이 글의 코드 예시는 SAP RAP100 워크숍의 Travel 시나리오를 기반으로 합니다. Persistent table은 zrap100_atravsol, CDS Entity는 ZRAP100_R_TravelTP_SOL 형태를 가정합니다. 실습 환경에 따라 접미사(SOL 등)가 달라질 수 있으므로 본인의 네이밍 규칙에 맞게 치환하시기 바랍니다.
4. 핵심 개념 — Validation, Determination, Action의 역할 분담
Managed 시나리오에서 RAP 런타임이 CRUD를 자동 처리해주지만, 비즈니스 로직은 개발자가 직접 작성해야 합니다. 이때 세 가지 메커니즘이 각각 다른 시점과 목적으로 동작합니다.
Validation (검증)
데이터가 저장(save)되기 직전에 실행되어 비즈니스 규칙을 검증합니다. 예를 들어 "CustomerID가 실제 존재하는 고객인가?", "시작일이 종료일보다 앞서는가?" 같은 검증입니다. 비유하자면 은행 창구에서 서류를 제출할 때 직원이 최종 확인하는 단계에 해당합니다. Validation이 실패하면 저장이 거부되고, failed와 reported 구조체를 통해 오류 메시지가 사용자에게 전달됩니다.
Determination (자동 결정)
레코드가 생성(create) 또는 수정(update)될 때 특정 필드를 자동으로 설정합니다. 예를 들어 "Travel을 새로 만들면 상태를 자동으로 Open으로 설정"하는 것입니다. 비유하자면 새 주문서를 작성하면 시스템이 자동으로 "접수" 도장을 찍어주는 것과 같습니다. on modify 시점에 실행되며, MODIFY ENTITIES IN LOCAL MODE를 사용해 BO 내부에서 데이터를 변경합니다.
Action (사용자 액션)
사용자가 UI 버튼을 눌러 명시적으로 트리거하는 비즈니스 오퍼레이션입니다. "여행 승인", "여행 거부", "할인 적용" 같은 동작이 해당됩니다. Instance Action은 기존 인스턴스를 변경하고, Factory Action은 새 인스턴스를 생성합니다. 비유하자면 워크플로우에서 "승인" 버튼을 클릭하는 행위 자체입니다.
실행 시점 요약: Determination은 데이터 변경 직후(on modify), Validation은 저장 직전(on save), Action은 사용자 요청 시점에 각각 실행됩니다. 이 순서를 이해하는 것이 RAP 비즈니스 로직 설계의 핵심입니다.
5. BDEF(Behavior Definition) 선언
모든 Validation, Determination, Action은 Behavior Definition 파일에 먼저 선언해야 합니다. 아래는 Travel BO의 전체 BDEF 예시입니다.
주요 문법 포인트를 정리합니다.
validation ... on save { create; field ...; }— 저장 시점에 실행되며,create나update트리거와 감시 대상 필드를 지정합니다.determination ... on modify { create; }— 수정 시점(레코드 생성 포함)에 실행됩니다.action ... parameter ... result [1] $self;— 입력 파라미터가 있는 인스턴스 액션입니다.$self는 동일 엔티티를 결과로 반환함을 의미합니다.factory action ... [1];— 새 인스턴스를 생성하는 팩토리 액션입니다.draft determine action Prepare— Draft 저장(Prepare) 시 지정된 Validation들을 미리 실행하여 사용자에게 피드백을 줍니다.
6. Validation 구현
validateCustomer — 고객 존재 여부 검증
Validation 메서드의 기본 패턴은 다음과 같습니다: (1) READ ENTITIES로 현재 BO 데이터를 읽고, (2) 비즈니스 규칙을 검증한 후, (3) 실패 시 failed와 reported에 오류를 추가합니다.
validateDates — 날짜 유효성 검증
핵심 포인트: %element 필드를 if_abap_behv=>mk-on으로 설정하면, Fiori Elements UI에서 해당 필드에 빨간색 오류 표시가 나타납니다. 이것이 RAP의 필드 수준 오류 바인딩 메커니즘입니다.
7. Determination 구현
Determination에서 주목할 점은 MODIFY ENTITIES IN LOCAL MODE를 사용한다는 것입니다. LOCAL MODE는 권한 검사(authorization check)와 기타 Validation을 건너뛰고 BO 내부에서 직접 데이터를 수정합니다. Determination은 BO 자체의 내부 로직이므로 이 모드가 적절합니다.
또한 Determination은 failed/reported를 반환하지 않는 것이 일반적입니다. 자동 설정 로직이므로 실패할 상황이 거의 없기 때문입니다. 만약 외부 데이터 의존성이 있다면 Validation에서 별도로 검증하는 것이 권장되는 패턴입니다.
8. Action 구현 — Instance Action과 Factory Action
Instance Action: acceptTravel / rejectTravel
상태를 변경하는 단순한 Instance Action 패턴입니다.
Instance Action with Parameter: deductDiscount
deductDiscount는 사용자가 할인율을 입력받아 총 가격에서 차감하는 액션입니다. parameter 키워드로 선언한 Abstract Entity가 입력 구조체로 사용됩니다.
Factory Action: copyTravel
Factory Action은 기존 인스턴스를 기반으로 새 인스턴스를 생성합니다. 기존 Action과 달리 MODIFY ENTITIES ... CREATE를 사용하며, mapped 파라미터를 통해 새로 생성된 키를 반환합니다.
Factory Action의 핵심은 %cid(Content ID)를 사용하여 아직 키가 부여되지 않은 새 인스턴스를 식별한다는 점입니다. Early Numbering 설정이 되어 있으면 RAP 프레임워크가 자동으로 새 TravelID를 할당합니다.
9. Draft와 Prepare Action 연동
Draft 시나리오에서는 사용자가 데이터를 입력하는 동안 아직 Active 테이블에 저장되지 않은 Draft 상태로 유지됩니다. 이때 Prepare Action이 중요한 역할을 합니다.
Prepare의 동작 원리
- 사용자가 Fiori UI에서 저장 버튼을 누르면, 먼저
Prepare가 실행됩니다. - Prepare는 BDEF에서 지정한 Validation들(
validateCustomer,validateDates)을 Draft 데이터에 대해 실행합니다. - Validation이 통과하면
Activate가 진행되어 Draft가 Active 테이블로 이동합니다. - Validation이 실패하면 사용자에게 오류 메시지가 표시되고, Draft 상태가 유지됩니다.
BDEF에서의 선언을 다시 보면:
이 선언만으로 Draft-Active 전환 시 자동으로 양쪽 Validation이 호출됩니다. 별도의 Prepare 메서드 구현은 필요하지 않으며, RAP 프레임워크가 내부적으로 처리합니다.
Draft 표준 액션 정리
| Draft Action역할 | |
Edit | Active 인스턴스를 Draft로 전환 (편집 시작) |
Activate optimized | Draft를 Active로 전환 (변경분만 저장) |
Discard | Draft를 삭제 (편집 취소) |
Resume | 이전에 중단된 Draft 편집을 재개 |
Prepare | Activate 전 Validation 사전 실행 |
삽질 노트 — 자주 만나는 함정
Q1. Validation이 실행되지 않는 것 같습니다.
BDEF에서 field 키워드로 지정한 필드가 실제로 변경되었는지 확인하시기 바랍니다. 예를 들어 validateDates는 field BeginDate, EndDate로 선언되어 있으므로, 이 필드가 변경되지 않으면 트리거되지 않습니다. 또한 create/update 트리거 조건도 확인이 필요합니다.
Q2. Determination에서 MODIFY ENTITIES 호출 시 authorization 오류가 발생합니다.
IN LOCAL MODE를 빠뜨렸을 가능성이 높습니다. Determination은 BO 내부 로직이므로 반드시 MODIFY ENTITIES OF ... IN LOCAL MODE를 사용해야 합니다. LOCAL MODE 없이 호출하면 권한 검사가 다시 실행되어 무한 루프나 권한 오류가 발생할 수 있습니다.
Q3. Factory Action 실행 후 새 레코드의 키 값이 비어 있습니다.
Early Numbering이 설정되어 있는지 확인하시기 바랍니다. BDEF에 early numbering이 선언되어 있으면 earlynumbering_create 메서드에서 키 할당 로직이 구현되어야 합니다. Late Numbering을 사용하는 경우 adjust_numbers 메서드에서 처리됩니다.
Q4. %tky와 %key의 차이가 무엇인가요?
%key는 BO의 비즈니스 키(예: TravelID)만 포함하고, %tky(transactional key)는 Draft 시나리오에서 %is_draft 플래그까지 포함합니다. Draft를 사용하는 BO에서는 항상 %tky를 사용하는 것이 권장됩니다.
더 파볼 주제
- Dynamic Feature Control — 상태에 따라 Action 버튼을 활성화/비활성화하는 방법 (예: 이미 승인된 Travel에서 acceptTravel 버튼 숨기기)
- Side Effects — 특정 필드 변경 시 UI를 자동 새로고침하여 Determination 결과를 즉시 반영
- Authorization Control — instance/global 권한 검사 구현
- Unmanaged Save — Managed 시나리오에서 저장 로직을 커스터마이징해야 하는 경우
- Composition (하위 엔티티) — Travel-Booking 같은 부모-자식 구조에서 Validation/Determination 전파
더 읽어볼 자료
- SAP Help — RAP Validations
- SAP Help — RAP Determinations
- SAP Help — RAP Actions
- SAP Help — Draft Handling in RAP
- GitHub SAP-samples — RAP100 워크숍 전체 코드
- SAP Community — RAP Topic Page
- SAP Developers Tutorial — RAP Validation 실습
⚠️ 비공식 콘텐츠 안내
본 게시글은 btpstacks.com의 독립 학습 콘텐츠이며 SAP SE와 무관합니다. 공식 문서는 help.sap.com을 참고하세요.
SAP, ABAP, SAP BTP, SAPUI5, SAP Fiori는 독일 및 기타 국가에서 SAP SE의 상표 또는 등록상표입니다.
댓글 0
아직 댓글이 없습니다.