SAP RAP Validation and Precheck: Definitions, Examples & Best Practices

SAP RAP Validation and Precheck: Definitions, Examples & Best Practices

SAP RAP

When working with SAP RAP (RESTful Application Programming), understanding the difference between validation and precheck mechanisms is crucial for building robust business applications. Both serve important but distinct purposes in ensuring data integrity and business rule compliance.

What is Validation in SAP RAP?

Validation in SAP RAP is a mechanism to check business logic and data consistency during data modification operations (CREATE, UPDATE, DELETE). Validations are triggered automatically by the RAP framework during the save sequence and can prevent data from being saved if business rules are violated.

What is Precheck in SAP RAP?

Precheck in SAP RAP is a mechanism to perform early validation checks before the actual business logic execution. It's designed to quickly identify and report issues without executing expensive operations, providing fast feedback to users.

Complete Example: Behavior Definition

Let's look at a complete behavior definition for a billing document application that includes both precheck for create operations and a validation:

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

define behavior for zsac_r_bill_headtp
persistent table zsac_bill_header
lock master
authorization master ( instance )
{
  create ( precheck );
  update;
  delete;

  field ( mandatory : create, readonly : update ) BillId;
  
  // Validation definition
  validation validateAmount on save { field NetAmount; create; update; }

  mapping for zsac_bill_header
    {
      BillId             = bill_id;
      BillType           = bill_type;
      BillDate           = bill_date;
      CustomerId         = customer_id;
      NetAmount          = net_amount;
      Currency           = currency;
      SalesOrg           = sales_org;
      CreatedBy          = createdby;
      CreateDat          = createdat;
      LastChangedBy      = lastchangedby;
      LastChangeDat      = lastchangedat;
      LocalLastChangeDat = locallastchangedat;
    }
}

Code Explanation

Behavior Definition Breakdown

Precheck Definition:

  • create ( precheck ); - This declares that create operation should include a precheck phase
  • The precheck is implicitly defined by adding (precheck) to the operation
  • No explicit validation syntax is needed in the behavior definition

Validation Definition:

  • validation ValidateAmount on save { field NetAmount; create; update; } - This explicitly defines a validation
  • ValidateAmount is the validation name that must match the method name in the implementation
  • on save indicates when the validation is triggered
  • { field NetAmount; create; update; } specifies which fields trigger this validation when created and changed

Behavior Implementation Class

Here's the complete implementation class showing both precheck and validation methods:

CLASS lhc_zsac_r_bill_headtp DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.

    METHODS validateamount FOR VALIDATE ON SAVE
      IMPORTING keys FOR zsac_r_bill_headtp~validateamount.
    METHODS precheck_create FOR PRECHECK
      IMPORTING entities FOR CREATE zsac_r_bill_headtp.
    
ENDCLASS.

CLASS lhc_zsac_r_bill_headtp IMPLEMENTATION.


  METHOD validateAmount.

    READ ENTITIES OF zsac_r_bill_headtp IN LOCAL MODE
        ENTITY zsac_r_bill_headtp
        FIELDS ( NetAmount ) WITH CORRESPONDING #( keys )
        RESULT DATA(lt_billdoc).

    LOOP AT lt_billdoc INTO DATA(ls_billdoc).
      IF ls_billdoc-NetAmount IS NOT INITIAL AND ls_billdoc-NetAmount < 1000.
        APPEND VALUE #( %tky = ls_billdoc-%tky ) TO failed-zsac_r_bill_headtp.
        APPEND VALUE #( %tky = ls_billdoc-%tky
                        %element-NetAmount = if_abap_behv=>mk-on
                        %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error
                                                      text = 'Net Amount cannot be less than 1000' )
                       ) TO reported-zsac_r_bill_headtp.
      ENDIF.
    ENDLOOP.

  ENDMETHOD.

  METHOD precheck_create.
*  Pre-check will not work after draft implementation. Why?

    LOOP AT entities INTO DATA(ls_entity).

      IF ls_entity-CustomerId IS NOT INITIAL.

        SELECT SINGLE * FROM /DMO/I_Customer
            WHERE CustomerID = @ls_entity-CustomerId
            INTO @DATA(ls_customer).
        IF sy-subrc NE 0.
          APPEND VALUE #( %key = ls_entity-%key ) TO failed-zsac_r_bill_headtp.
          APPEND VALUE #( %key = ls_entity-%key
                        %element-CustomerId = if_abap_behv=>mk-on
                        %msg = new_message_with_text( severity = if_abap_behv_message=>severity-error
                                                      text = 'Customer does not exists' )
                       ) TO reported-zsac_r_bill_headtp.
        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDMETHOD.

ENDCLASS.

Code Explanation

Implementation Class Breakdown

Precheck Method (precheck_create):

  • Purpose: Performs quick customer existance checks before expensive business logic
  • Timing: Executed early in the processing cycle
  • Logic: Simple database lookup at table /DMO/I_Customer
  • Performance: Lightweight operation, no database reads for business data
  • Error Handling: Immediately blocks processing if customer does not exists

Validation Method (validateAmount):

  • Purpose: Validates business rules and data consistency
  • Timing: Executed during the save sequence after business logic
  • Logic: Reads entity data and performs business rule validation for minumum amount
  • Performance: Can perform complex operations including database access
  • Error Handling: Prevents save operation if validation fails

Common Error Handling Pattern: Both methods use the same pattern for error reporting:

  1. Add failed keys to failed-zsac_r_bill_headtp table
  2. Add descriptive error messages to reported-zsac_r_bill_headtp table
  3. Use appropriate message severity levels

Key Differences

Aspect Validation Precheck
Execution Timing Trigger during the save sequence (specifically, in the check_before_save phase), after data has entered the transactional buffer. Trigger before operation execution (CREATE, UPDATE, DELETE or any custom action) before the transactional buffer is updated.
Purpose Validate business rules and data consistency Check if operation is allowed to proceed
Trigger Point Automatically triggered during save during create and/or update operation Triggered before each operation (if specified)
Error Handling Can prevent save operation Can prevent operation from starting
Performance Impact Executed once during save as it's part of save sequence  Executed for each operation as it's part of interaction phase
Method Signature METHODS validateamount FOR VALIDATE ON SAVE
      IMPORTING keys FOR zsac_r_bill_headtp~validateAmount.
METHODS precheck_create FOR PRECHECK
      IMPORTING entities FOR CREATE zsac_r_bill_headtp.
Trigger Specificity Trigger only when specified field is changed. Trigger when the operation is executed. Prechecks are not applicable on field level.

When to Use Each

Use Precheck when:

  • Performing authorization checks
  • Quick data format validation
  • Early rejection of obviously invalid requests
  • Avoiding expensive operations for unauthorized users

Use Validation when:

  • Checking business rules
  • Validating data consistency across entities
  • Performing complex validation logic
  • Ensuring data integrity before save

Understanding these mechanisms and their proper usage will help you build more efficient and robust SAP RAP applications with better user experience and performance.


If you enjoyed this walkthrough and want to explore more SAP RAP scenarios, from simple CRUD apps to real-world enhancements and API integrations, check out the full blog series:

πŸ”— Explore the SAP RAP Series

Each post is crafted to be beginner-friendly yet practical enough for working professionals trying to get hands-on with ABAP RAP.

Thanks for reading ☺️