RAP에서 Function과 Action, 무엇이 다른가
SAP RAP(RESTful Application Programming Model)에서는 비즈니스 로직을 구현하는 방법으로 Action과 Function 두 가지를 제공합니다. 이름이 비슷해 혼동하기 쉽지만, OData 의미론, 부작용(Side Effect), 트랜잭션 처리에서 근본적으로 다릅니다. 잘못 사용하면 OData 클라이언트가 캐싱 오류를 내거나, 데이터 변경이 롤백될 수 있습니다.
차이 1: 부작용(Side Effect)
-- Action: 데이터를 변경한다 (Side Effect 있음)
-- POST 메서드로 호출됨
-- Function: 데이터를 읽기만 한다 (Side Effect 없음)
-- GET 메서드로 호출됨
-- Behavior Definition에서 선언
define behavior for ZC_SalesOrder alias SalesOrder {
-- Action: 주문 확정 (상태 변경 — Side Effect 있음)
action confirmOrder result [1] $self;
-- Function: 주문 금액 재계산 (조회만 — Side Effect 없음)
function calculateTotals
result [1] ZD_OrderTotals;
}
OData 호출 형태 비교
-- Action은 POST로 호출 (데이터 변경)
-- POST /SalesOrders('SO-001')/ZC_SalesOrder.confirmOrder
-- Body: {} (또는 파라미터)
-- Function은 GET으로 호출 (조회만)
-- GET /SalesOrders('SO-001')/ZC_SalesOrder.calculateTotals()
-- Body 없음, URL 파라미터로 전달
이 차이가 중요한 이유: 브라우저와 CDN은 GET 요청을 캐시합니다. Function이 데이터를 변경하면 캐시로 인해 클라이언트가 변경 결과를 받지 못할 수 있습니다.
Action 구현 예제
" Action 구현 — 데이터 변경
CLASS zbp_sales_order DEFINITION.
PUBLIC SECTION.
METHODS confirmorder FOR MODIFY
IMPORTING keys FOR ACTION SalesOrder~confirmOrder.
ENDCLASS.
CLASS zbp_sales_order IMPLEMENTATION.
METHOD confirmorder.
LOOP AT keys ASSIGNING FIELD-SYMBOL().
" 주문 상태를 CONFIRMED로 변경
MODIFY ENTITIES OF ZC_SalesOrder IN LOCAL MODE
ENTITY SalesOrder
UPDATE FIELDS ( status confirmed_at confirmed_by )
WITH VALUE #(
( %tky = -%tky
status = 'CONFIRMED'
confirmed_at = cl_abap_context_info=>get_system_date( )
confirmed_by = cl_abap_context_info=>get_user_technical_name( ) )
).
" 결과 반환 (변경된 엔티티)
READ ENTITIES OF ZC_SalesOrder IN LOCAL MODE
ENTITY SalesOrder ALL FIELDS WITH CORRESPONDING #( keys )
RESULT DATA(lt_orders).
result = VALUE #( FOR order IN lt_orders
( %tky = order-%tky
%param = order ) ).
ENDLOOP.
ENDMETHOD.
ENDCLASS.
Function 구현 예제
" Function 구현 — 읽기만
CLASS zbp_sales_order DEFINITION.
PUBLIC SECTION.
METHODS calculatetotals FOR READ
IMPORTING keys FOR FUNCTION SalesOrder~calculateTotals
RESULT result.
ENDCLASS.
CLASS zbp_sales_order IMPLEMENTATION.
METHOD calculatetotals.
LOOP AT keys ASSIGNING FIELD-SYMBOL().
" 아이템 조회 (데이터 변경 없음)
READ ENTITIES OF ZC_SalesOrder IN LOCAL MODE
ENTITY SalesOrderItem ALL FIELDS
WITH VALUE #( ( %parent_key = -%tky ) )
RESULT DATA(lt_items).
" 합계 계산 (메모리 내 연산만)
DATA(lv_net) = REDUCE decfloat34( INIT s = 0
FOR item IN lt_items
NEXT s = s + item-net_amount ).
DATA(lv_tax) = lv_net * '0.1'.
DATA(lv_gross) = lv_net + lv_tax.
" 결과 반환 (DB 변경 없음)
APPEND VALUE #(
%tky = -%tky
%param = VALUE ZD_OrderTotals(
net_amount = lv_net
tax_amount = lv_tax
gross_amount = lv_gross
)
) TO result.
ENDLOOP.
ENDMETHOD.
ENDCLASS.
차이 2: FOR MODIFY vs FOR READ
-- Action 구현: FOR MODIFY
-- 트랜잭션 처리 대상, COMMIT/ROLLBACK에 포함
METHODS confirmorder FOR MODIFY
IMPORTING keys FOR ACTION SalesOrder~confirmOrder.
-- Function 구현: FOR READ
-- 트랜잭션 무관, 읽기 전용
METHODS calculatetotals FOR READ
IMPORTING keys FOR FUNCTION SalesOrder~calculateTotals
RESULT result.
차이 3: 파라미터 전달 방식
-- Action 파라미터: POST Body로 전달
action cancelOrder parameter ZD_CancelParam result [1] $self;
-- POST /Orders('key')/cancelOrder
-- Body: {"CancelReason": "고객 요청", "RefundRequired": true}
-- Function 파라미터: URL로 전달
function getOrdersByPeriod(
P_StartDate: abap.dats,
P_EndDate: abap.dats
) result [0..*] $self;
-- GET /getOrdersByPeriod(P_StartDate='20260101',P_EndDate='20260131')
선택 기준 요약
- 데이터를 변경하는가? → Action (POST)
- 조회만 하는가? → Function (GET)
- 트랜잭션에 포함되어야 하는가? → Action
- 캐싱이 허용되는가? → Function
공식 문서
RAP Function과 Action 전체 가이드는 SAP RAP 공식 문서에서 확인하세요.
댓글 0
아직 댓글이 없습니다.