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 that includes both precheck for update operations and a validation:

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

define behavior for ZI_TRAVEL alias Travel
persistent table ztravel
lock master
authorization master ( instance )
{
  create;
  update ( precheck );
  delete;
  
  field ( readonly ) travel_id;
  field ( mandatory ) agency_id, customer_id;
  
  // Validation definition
  validation ValidateCustomer on save { field customer_id; }
}

Code Explanation

Behavior Definition Breakdown

Precheck Definition:

  • update ( precheck ); - This declares that update operations 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 ValidateCustomer on save { field customer_id; } - This explicitly defines a validation
  • ValidateCustomer is the validation name that must match the method name in the implementation
  • on save indicates when the validation is triggered
  • { field customer_id; } specifies which fields trigger this validation when changed

Behavior Implementation Class

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

CLASS lhc_Travel DEFINITION INHERITING FROM cl_abap_behavior_handler.
  PRIVATE SECTION.
    " Precheck method for update operation
    METHODS precheck_update FOR PRECHECK
      IMPORTING entities FOR UPDATE Travel.
      
    " Validation method
    METHODS validate_customer FOR VALIDATE ON SAVE
      IMPORTING keys FOR Travel~ValidateCustomer.
ENDCLASS.

CLASS lhc_Travel IMPLEMENTATION.
  
  METHOD precheck_update.
    " Quick authorization check before processing update
    LOOP AT entities INTO DATA(entity).
      " Perform lightweight authorization check
      AUTHORITY-CHECK OBJECT 'Z_TRAVEL'
        ID 'ACTVT' FIELD '02'  " Update activity
        ID 'AGENCY' FIELD entity-agency_id.
      
      IF sy-subrc <> 0.
        " Add to failed table
        APPEND VALUE #( %tky = entity-%tky ) TO failed-travel.
        
        " Add error message
        APPEND VALUE #( %tky = entity-%tky
                       %msg = new_message_with_text(
                         severity = if_abap_behv_message=>severity-error
                         text = |No authorization to update travel for agency { entity-agency_id }| ) )
          TO reported-travel.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.

  METHOD validate_customer.
    " Read travel data for validation
    READ ENTITIES OF zi_travel_m IN LOCAL MODE
      ENTITY Travel
        FIELDS ( customer_id )
        WITH CORRESPONDING #( keys )
      RESULT DATA(travels).

    " Check if customer exists in master data
    SELECT customer_id FROM /dmo/customer
      FOR ALL ENTRIES IN travels
      WHERE customer_id = travels-customer_id
      INTO TABLE @DATA(valid_customers).

    " Validate each customer and report errors
    LOOP AT travels INTO DATA(travel).
      IF NOT line_exists( valid_customers[ customer_id = travel-customer_id ] ).
        " Add to failed table
        APPEND VALUE #( %tky = travel-%tky ) TO failed-travel.
        
        " Add validation error message
        APPEND VALUE #( %tky = travel-%tky
                       %msg = new_message_with_text(
                         severity = if_abap_behv_message=>severity-error
                         text = |Customer { travel-customer_id } does not exist in master data| ) )
          TO reported-travel.
      ENDIF.
    ENDLOOP.
  ENDMETHOD.
  
ENDCLASS.

Code Explanation

Implementation Class Breakdown

Precheck Method (precheck_update):

  • Purpose: Performs quick authorization checks before expensive business logic
  • Timing: Executed early in the processing cycle
  • Logic: Simple authority check using AUTHORITY-CHECK
  • Performance: Lightweight operation, no database reads for business data
  • Error Handling: Immediately blocks processing if authorization fails

Validation Method (validate_customer):

  • Purpose: Validates business rules and data consistency
  • Timing: Executed during the save sequence after business logic
  • Logic: Reads entity data and performs database lookups for validation
  • 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-travel table
  2. Add descriptive error messages to reported-travel 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 validatecurrency FOR VALIDATE ON SAVE
      IMPORTING keys FOR zsac_i_billheader~validatecurrency.
METHODS precheck_update FOR PRECHECK
      IMPORTING entities FOR UPDATE zsac_i_billheader.
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.