RAP

트랜잭션 없이 개발 — RAP vs BOPF 결정적 차이 #shorts #SAP #RAP

▶ YouTube에서 보기

1. BOPF의 시대: 왜 새로운 모델이 필요했나

2010년대 초반 SAP는 ABAP 기반 트랜잭션 애플리케이션의 비즈니스 로직을 표준화하기 위해 BOPF(Business Object Processing Framework)를 도입했습니다. 당시 ABAP 개발자들은 화면(Dynpro), 비즈니스 로직, 데이터 영속화 계층이 강하게 결합된 모놀리식 구조에서 일하고 있었고, 동일한 검증·결정·액션 코드를 여러 트랜잭션에 반복 작성하는 비효율을 겪고 있었습니다.

BOPF는 이러한 문제를 노드(Node) 트리, 액션(Action), 결정(Determination), 검증(Validation)이라는 메타데이터 모델로 해결하려 했습니다. SAP Fiori 초기 버전, S/4HANA의 일부 핵심 객체(예: Sales Order, Purchase Requisition)는 BOPF 위에 구축되어 일관된 트랜잭션 처리와 락(lock) 관리를 제공받았습니다.

그러나 BOPF는 시간이 흐르며 한계를 드러냈습니다. 첫째, BOPF 자체가 Fiori 시대에 표준이 된 OData 서비스와 직접적인 결합점이 없어 SADL(Service Adaptation Definition Language)이나 별도의 Gateway 서비스 빌더를 거쳐야 했습니다. 둘째, 메타데이터는 SAP GUI 트랜잭션(/BOBF/CONF_UI 등)에 종속되어 있어 Git 친화적이지 않았습니다. 셋째, 로직 구현이 여러 BOPF 클래스에 흩어져 디버깅과 유지보수가 까다로웠습니다. 클라우드 우선, API 우선 시대로 진입하며 SAP은 더 선언적이고, CDS와 ABAP 언어 자체에 통합된 새로운 프로그래밍 모델이 필요했습니다.

2. RAP의 등장: RESTful ABAP Programming Model 개요

RAP(RESTful ABAP Programming Model)은 SAP S/4HANA Cloud(2018년 1811 릴리스 전후)와 ABAP Platform 1909 이상에서 본격 도입된 차세대 애플리케이션 프로그래밍 모델입니다. 핵심 사상은 다음과 같이 요약됩니다.

  • CDS(Core Data Services) 중심: 데이터 모델은 모두 CDS View로 선언
  • 선언적 동작 정의: Behavior Definition(BDEF)으로 CRUD, 액션, 검증을 한 파일에 명시
  • OData v4 표준 게시: Service Definition + Service Binding으로 즉시 RESTful 서비스 노출
  • Git/abapGit 친화적: 모든 산출물이 텍스트 기반 ABAP 객체로 ADT(Eclipse)에서 관리
  • 클라우드 호환성: Released API만 사용하면 ABAP Cloud와 Steampunk(BTP ABAP Environment) 모두에서 동일 코드 동작

RAP은 단순히 BOPF의 대체재가 아니라, Fiori Elements, OData v4, Embedded Steampunk, BTP ABAP Environment까지 아우르는 통합 개발 패러다임으로 설계되었습니다. 일반적으로 ABAP Platform 2020 이상에서는 신규 개발 시 RAP이 권장됩니다.

3. 아키텍처 비교: 두 모델의 핵심 구조 차이

두 프레임워크의 차이를 한눈에 비교하면 다음과 같습니다.

구분BOPFRAP
모델 정의BOPF Configuration UI (트랜잭션)CDS + Behavior Definition (텍스트)
데이터 계층DDIC 테이블 + BOPF 노드CDS View (Root, Child)
비즈니스 로직Determination/Validation/Action 클래스Behavior Pool(ABP) + EML
OData 노출SADL 또는 SEGW 별도 작업Service Definition + Binding
락 관리BOPF Lock ObjectRAP Lock Master + Draft
버전 관리제한적 (트랜잭션 종속)abapGit 완전 지원
OData 버전주로 v2v2 / v4 동시 지원

비유하자면 BOPF는 Visual Basic의 폼 디자이너처럼 화면(트랜잭션) 안에서 객체를 클릭으로 조립하는 방식이고, RAP은 React + TypeScript처럼 모든 정의가 선언적 텍스트 파일에 담겨 있어 코드 리뷰와 CI/CD가 자연스럽게 들어맞는 구조입니다.

4. CDS View와 Behavior Definition: RAP의 두 기둥

RAP을 이해하는 가장 빠른 길은 두 가지 산출물의 역할을 분리해서 보는 것입니다.

CDS View는 데이터 모델을 정의합니다. 일반 CDS View가 아닌 root view entitycomposition 키워드로 트리 구조(부모-자식 관계)를 선언하면 RAP이 이를 비즈니스 객체의 골격으로 인식합니다.

Behavior Definition(BDEF)은 그 데이터 모델 위에서 어떤 동작을 허용할지 선언합니다. 어떤 필드가 읽기 전용인지, 어떤 액션(예: 승인, 반려)이 존재하는지, 어떤 검증(validation)과 결정(determination)이 트리거되는지를 텍스트로 명세합니다. 실제 구현 코드(Behavior Pool, ABP 클래스)는 BDEF가 가리키는 ABAP 클래스에서 메서드 단위로 작성됩니다.

@AccessControl.authorizationCheck: #CHECK
define root view entity ZC_SalesOrder
  as select from zsales_ord_hdr as Header
  composition [0..*] of ZC_SalesOrderItem as _Items
{
  key Header.order_id      as OrderId,
      Header.customer_id   as CustomerId,
      Header.order_status  as OrderStatus,
      Header.total_amount  as TotalAmount,
      Header.currency_code as CurrencyCode,
      Header.created_at    as CreatedAt,
      _Items
}

이 두 산출물은 명확히 역할이 분리되어 있어 데이터 모델 변경과 동작 변경이 서로 간섭하지 않습니다. BOPF에서는 노드 구조와 액션이 같은 메타데이터 안에 묶여 있어 작은 변경에도 광범위한 영향이 발생했던 점과 대비됩니다.

5. 실전 예제: SalesOrder 조회 서비스를 RAP으로 구성하기

아래 예제는 ABAP Platform 2022 / S/4HANA 2022 환경 기준으로, 매니지드(managed) 시나리오의 SalesOrder 서비스를 구성하는 흐름입니다.

managed implementation in class zbp_c_salesorder unique;
strict ( 2 );

define behavior for ZC_SalesOrder alias SalesOrder
persistent table zsales_ord_hdr
lock master
authorization master ( instance )
{
  field ( readonly ) OrderId, CreatedAt;
  field ( mandatory ) CustomerId, TotalAmount, CurrencyCode;

  create;
  update;
  delete;

  association _Items { create; }

  validation validateAmount on save { field TotalAmount; }
  determination calculateTotal on modify { field OrderStatus; }
  action ( features : instance ) approveOrder result [1] $self;
}
CLASS lhc_salesorder IMPLEMENTATION.

  METHOD validateAmount.
    READ ENTITIES OF zc_salesorder IN LOCAL MODE
      ENTITY SalesOrder
        FIELDS ( TotalAmount CurrencyCode )
        WITH CORRESPONDING #( keys )
      RESULT DATA(orders).

    LOOP AT orders INTO DATA(order).
      IF order-TotalAmount <= 0.
        APPEND VALUE #( %tky = order-%tky ) TO failed-salesorder.
        APPEND VALUE #( %tky  = order-%tky
                        %msg  = new_message(
                          id       = 'ZSO_MSG'
                          number   = '001'
                          severity = if_abap_behv_message=>severity-error )
                      ) TO reported-salesorder.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD approveOrder.
    MODIFY ENTITIES OF zc_salesorder IN LOCAL MODE
      ENTITY SalesOrder
        UPDATE FIELDS ( OrderStatus )
        WITH VALUE #( FOR k IN keys
                      ( %tky        = k-%tky
                        OrderStatus = 'APPROVED' ) )
      REPORTED DATA(update_reported).

    result = VALUE #( FOR k IN keys ( %tky = k-%tky ) ).
  ENDMETHOD.

ENDCLASS.

Service Definition과 Binding까지 생성하면 Fiori Elements 미리보기가 즉시 가능합니다. Draft 활성화는 BDEF에 with draft를 추가해 Fiori Elements의 임시 저장 UX를 활성화합니다.

6. OData v4와 RAP의 통합

BOPF 기반 서비스는 일반적으로 OData v2로 노출되었고, Fiori Elements도 v2 어노테이션 모델 위에서 동작했습니다. RAP은 처음부터 OData v4를 1급 시민으로 지원합니다. v4는 다음과 같은 실무적 장점을 제공합니다.

  • Deep Insert/Update의 표준화로 트리 구조 저장이 단순화
  • $batch 처리 방식이 JSON 기반으로 개선되어 디버깅 용이
  • Singleton, Capabilities Vocabulary 등 모던 API 패턴 지원
  • Streaming, Delta Query로 대용량 처리 효율화

RAP에서는 Service Binding 시 V2/V4 중 선택이 가능하며, 동일한 Service Definition을 두 개의 Binding으로 재사용할 수 있어 레거시 클라이언트와 신규 클라이언트를 점진적으로 분리 마이그레이션할 수 있습니다.

7. BOPF에서 RAP으로 옮길 때 점검할 항목

기존 BOPF 자산을 RAP으로 이관할 때 일반적으로 권장되는 접근은 다음과 같습니다.

  1. 전수 분석: BOPF 노드별 Action/Determination/Validation을 표로 정리하고, 어떤 것이 화면용·내부 호출용인지 분리합니다.
  2. 데이터 모델 재설계: 기존 BOPF 노드를 그대로 옮기지 말고 CDS Composition 트리로 재설계합니다. 불필요한 중간 노드를 제거할 좋은 기회입니다.
  3. Unmanaged vs Managed 결정: 기존 BOPF가 호출하는 함수 모듈/Update Task 로직이 많다면 Unmanaged 시나리오로 감싸 점진 이행하고, 신규 객체는 Managed로 작성합니다.
  4. 락 전략 재검토: BOPF Lock Object를 RAP의 Lock Master/Dependent 모델로 다시 매핑합니다.
  5. OData 클라이언트 영향도: 기존 v2 소비자(Fiori 앱, 외부 시스템)가 있다면 v2 Binding을 한동안 병행 유지합니다.
Q1. BOPF 액션을 RAP 액션으로 1:1 매핑하면 되나요? A. 대부분 가능하지만, BOPF의 일부 Background Action은 RAP의 Internal Action이나 별도 백그라운드 작업(Job)으로 분리하는 것이 권장됩니다.
Q2. CDS View만 만들면 자동으로 RAP이 되나요? A. 아닙니다. Behavior Definition과 Service Definition/Binding이 함께 있어야 RAP 서비스로 동작합니다.
Q3. EML에서 LOCAL MODE는 언제 쓰나요? A. Behavior Pool 내부에서 권한·결정·검증을 건너뛰고 일관된 트랜잭션 상태를 다룰 때 사용합니다.
Q4. ABAP Cloud에서 BOPF를 계속 쓸 수 있나요? A. BTP ABAP Environment 및 ABAP Cloud 개발 모델에서는 BOPF API가 Released 되어 있지 않아 신규 사용이 권장되지 않습니다.

8. RAP이 필요한 팀과 아직 BOPF가 맞는 팀

모든 팀이 즉시 RAP으로 옮겨야 하는 것은 아닙니다. 다음 기준으로 판단하면 의사결정이 단순해집니다.

  • RAP 권장: S/4HANA 2020 이상, ABAP Cloud/Steampunk 타깃, Fiori Elements + OData v4 신규 앱, Git 기반 협업, 외부 API 노출 빈도 높음
  • BOPF 유지 검토: ECC~S/4HANA 1909 환경에서 이미 다수의 BOPF 객체가 운영 중이며 단기 마이그레이션 리소스가 부족한 경우, 또는 SAP 표준 객체가 여전히 BOPF로 노출된 경우

Draft Handling 심화, Side Effects 어노테이션, Numbering 전략, Authorization Control, 그리고 Behavior Implementation의 Unit Test(CL_CDS_TEST_ENVIRONMENT, ABAP Behavior Test Double)는 RAP을 운영 수준으로 끌어올릴 때 반드시 거치는 영역입니다.

댓글 0

아직 댓글이 없습니다.