# SAP Gateway SEGW DPC_EXT CRUD Methods Generator for OData in ABAP

> Source: https://netray.co/tools/sap-gateway-segw-dpc-ext-crud-methods-generator
> Publisher: Netray (netray.co), AI and integration engineering for ERP and manufacturing systems.
> Section: Free Tools

## Short answer

Fill in your SEGW project, entity set and backend table and get the five redefined DPC_EXT methods for an OData V2 service, with $filter, $top, $skip and $inlinecount handled.

## Category

developer

## Erp

SAP NetWeaver / Basis

## Audience

- ABAP developer
- SAP Gateway developer
- SAP technical consultant

## Tool

**Kind:** template

**Output:** code

**Language:** abap

**Fields:**

#### SEGW project name

**Key:** project

**Type:** text

**Default:** ZPM_ORDERS

#### Entity type

**Key:** entity

**Type:** text

**Default:** Order

#### Entity set

**Key:** set

**Type:** text

**Default:** OrderSet

**Help:** Method names are <entity set>_GET_ENTITYSET and so on; SEGW shortens long set names to fit 30 characters, so copy the exact name from the DPC class.

#### DPC_EXT class

**Key:** dpc

**Type:** text

**Default:** ZCL_ZPM_ORDERS_DPC_EXT

#### Generated DPC base class

**Key:** dpcbase

**Type:** text

**Default:** ZCL_ZPM_ORDERS_DPC

#### Entity structure type

**Key:** ts

**Type:** text

**Default:** ZCL_ZPM_ORDERS_MPC=>TS_ORDER

#### Backend table

**Key:** table

**Type:** text

**Default:** AUFK

#### Fields to select (comma separated, same names as the entity structure)

**Key:** fields

**Type:** text

**Default:** aufnr, auart, ktext, werks, erdat

#### Key property (external name)

**Key:** extkey

**Type:** text

**Default:** Aufnr

#### Key ABAP field (upper case)

**Key:** abapkey

**Type:** text

**Default:** AUFNR

#### Mandatory field checked on create

**Key:** reqfield

**Type:** text

**Default:** ktext

**Blocks:**

#### 1. Class definition: redefine the methods

**Body:** " Project {{project}}, entity type {{entity}}, entity set {{set}}
" In SE24 or SEGW use Redefine; in ADT add the lines below.
CLASS {{dpc}} DEFINITION
  PUBLIC
  INHERITING FROM {{dpcbase}}
  CREATE PUBLIC.

  PROTECTED SECTION.
    METHODS {{set}}_get_entityset REDEFINITION.
    METHODS {{set}}_get_entity REDEFINITION.
    METHODS {{set}}_create_entity REDEFINITION.
    METHODS {{set}}_update_entity REDEFINITION.
    METHODS {{set}}_delete_entity REDEFINITION.
ENDCLASS.

#### 2. GET_ENTITYSET ($filter, $top, $skip, $inlinecount)

**Body:** METHOD {{set}}_get_entityset.
  DATA lr_key TYPE RANGE OF {{table}}-{{abapkey}}.
  DATA lt_entityset LIKE et_entityset.
  DATA lv_max TYPE i.

  " Filter on the key: technical context returns ABAP (internal) property names
  DATA(lt_filter) = io_tech_request_context->get_filter( )->get_filter_select_options( ).
  READ TABLE lt_filter INTO DATA(ls_filter) WITH KEY property = '{{abapkey}}'.
  IF sy-subrc = 0.
    lr_key = CORRESPONDING #( ls_filter-select_options ).
  ENDIF.

  " Read only what the page needs: $top plus $skip rows (0 means no limit)
  IF is_paging-top > 0.
    lv_max = is_paging-top + is_paging-skip.
  ENDIF.

  SELECT {{fields}}
    FROM {{table}}
    WHERE {{abapkey}} IN @lr_key
    ORDER BY {{abapkey}}
    INTO CORRESPONDING FIELDS OF TABLE @lt_entityset
    UP TO @lv_max ROWS.

  IF is_paging-skip > 0.
    DELETE lt_entityset FROM 1 TO is_paging-skip.
  ENDIF.

  IF io_tech_request_context->has_inlinecount( ) = abap_true.
    SELECT COUNT(*) FROM {{table}}
      WHERE {{abapkey}} IN @lr_key
      INTO @DATA(lv_count).
    es_response_context-inlinecount = lv_count.
  ENDIF.

  et_entityset = lt_entityset.
ENDMETHOD.

#### 3. GET_ENTITY (read one by key)

**Body:** METHOD {{set}}_get_entity.
  DATA lv_key TYPE {{table}}-{{abapkey}}.

  READ TABLE it_key_tab INTO DATA(ls_key) WITH KEY name = '{{extkey}}'.
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        textid  = /iwbep/cx_mgw_busi_exception=>business_error
        message = 'Key {{extkey}} missing in request'.
  ENDIF.

  " Add leading zeros, for example order 4711 becomes 000000004711
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = ls_key-value
    IMPORTING
      output = lv_key.

  SELECT SINGLE {{fields}}
    FROM {{table}}
    WHERE {{abapkey}} = @lv_key
    INTO CORRESPONDING FIELDS OF @er_entity.
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        textid  = /iwbep/cx_mgw_busi_exception=>business_error
        message = 'Entry not found'.
  ENDIF.
ENDMETHOD.

#### 4. CREATE_ENTITY (HTTP POST)

**Body:** METHOD {{set}}_create_entity.
  DATA ls_entity TYPE {{ts}}.

  io_data_provider->read_entry_data( IMPORTING es_data = ls_entity ).

  IF ls_entity-{{reqfield}} IS INITIAL.
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        textid  = /iwbep/cx_mgw_busi_exception=>business_error
        message = '{{reqfield}} is required'.
  ENDIF.

  " Create the business object with a released BAPI here and map
  " its RETURN messages to the exception above. Never INSERT into
  " standard tables such as {{table}} directly.

  er_entity = ls_entity.
ENDMETHOD.

#### 5. UPDATE_ENTITY (HTTP PUT)

**Body:** METHOD {{set}}_update_entity.
  DATA ls_entity TYPE {{ts}}.

  READ TABLE it_key_tab INTO DATA(ls_key) WITH KEY name = '{{extkey}}'.
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        textid  = /iwbep/cx_mgw_busi_exception=>business_error
        message = 'Key {{extkey}} missing in request'.
  ENDIF.

  io_data_provider->read_entry_data( IMPORTING es_data = ls_entity ).

  " The key in the URL wins over any key in the payload
  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = ls_key-value
    IMPORTING
      output = ls_entity-{{abapkey}}.

  " Change the business object with a released BAPI here.

  er_entity = ls_entity.
ENDMETHOD.

#### 6. DELETE_ENTITY (HTTP DELETE)

**Body:** METHOD {{set}}_delete_entity.
  DATA lv_key TYPE {{table}}-{{abapkey}}.

  READ TABLE it_key_tab INTO DATA(ls_key) WITH KEY name = '{{extkey}}'.
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        textid  = /iwbep/cx_mgw_busi_exception=>business_error
        message = 'Key {{extkey}} missing in request'.
  ENDIF.

  CALL FUNCTION 'CONVERSION_EXIT_ALPHA_INPUT'
    EXPORTING
      input  = ls_key-value
    IMPORTING
      output = lv_key.

  SELECT SINGLE @abap_true FROM {{table}}
    WHERE {{abapkey}} = @lv_key
    INTO @DATA(lv_exists).
  IF sy-subrc <> 0.
    RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
      EXPORTING
        textid  = /iwbep/cx_mgw_busi_exception=>business_error
        message = 'Entry not found'.
  ENDIF.

  " Set the deletion flag or status with a released BAPI here.
ENDMETHOD.

#### 7. Test requests in /IWFND/GW_CLIENT

**Body:** GET  /sap/opu/odata/sap/{{project}}_SRV/{{set}}?$filter={{extkey}} eq '4711'&$top=20&$skip=0&$inlinecount=allpages
GET  /sap/opu/odata/sap/{{project}}_SRV/{{set}}('000000004711')

For POST, PUT and DELETE first send a GET with header
  X-CSRF-Token: Fetch
then copy the returned token into the X-CSRF-Token header of the write request.

**Notes:** Written for SAP Gateway OData V2 (SEGW) on ABAP 7.50 or later (new Open SQL with @ host variables and inline declarations). Check in your DPC base class that the method names match the generated ones, that the entity structure components are named like the table fields you select, and that the service name follows your registration (default technical name is the project name plus _SRV). Use released BAPIs for writes.

## Content

**Intro:** This generator writes the five DPC_EXT method redefinitions behind a classic SEGW OData V2 service: entity set read with $filter and paging, single read, create, update and delete. Fill in your project, entity set, structure type and backend table and paste the result into your DPC_EXT class.

**Sections:**

#### How to use it: OData in SAP ABAP, step by step

**Body:** Create the project in SEGW, define the entity type and entity set (or import them from a DDIC structure), then Generate Runtime Objects. SEGW creates the MPC and DPC base classes plus the _EXT classes you own. Fill in the fields here with the exact names from that generation, paste block 1 into the DPC_EXT definition and blocks 2 to 6 into the implementation, and activate. Register the service on the hub in /IWFND/MAINT_SERVICE (Add Service, system alias, technical service name), then test it in /IWFND/GW_CLIENT using the requests in block 7.

**Bullets:**

- Regenerate runtime objects after every model change; the _EXT classes keep your code.
- Delete the method blocks you do not need, and their REDEFINITION lines.
- Keep the technical names: the URL uses the external property name, the technical request context uses the ABAP name.

#### What each method receives

**Body:** All five methods come from /IWBEP/IF_MGW_APPL_SRV_RUNTIME through the generated DPC class. GET_ENTITYSET gets IS_PAGING (TOP and SKIP from $top and $skip), IO_TECH_REQUEST_CONTEXT (filter, order, inlinecount) and returns ET_ENTITYSET and ES_RESPONSE_CONTEXT, where INLINECOUNT carries the total for $inlinecount=allpages. GET_ENTITY, UPDATE_ENTITY and DELETE_ENTITY get IT_KEY_TAB, a name/value table with external property names such as Aufnr. CREATE_ENTITY and UPDATE_ENTITY get IO_DATA_PROVIDER, whose READ_ENTRY_DATA fills your structure from the JSON or XML payload, and return ER_ENTITY. Errors go back to the client by raising /IWBEP/CX_MGW_BUSI_EXCEPTION with TEXTID business_error and a MESSAGE text.

#### Worked example: maintenance order service on AUFK

**Body:** With the defaults, a request for OrderSet?$filter=Aufnr eq '4711'&$top=20 reads AUFK through a range built from the filter, sorted by AUFNR, limited to 20 rows plus any $skip, and returns AUFNR, AUART, KTEXT, WERKS and ERDAT. OrderSet('000000004711') hits GET_ENTITY; the key is passed through CONVERSION_EXIT_ALPHA_INPUT so that a client sending 4711 still finds the order. A POST with a JSON body is mapped into TS_ORDER and rejected with a business error if KTEXT is empty. The write blocks deliberately leave the database change to a released BAPI, because writing AUFK directly skips status management, change documents and authority checks.

#### Gotchas and where to look when it fails

**Body:** A 403 on POST almost always means a missing or stale CSRF token: fetch it with a GET first in the same session. A 500 with no detail is logged on the hub in /IWFND/ERROR_LOG and on the backend in /IWBEP/ERROR_LOG, both with the call stack. If the filter is ignored, check that you read the property by its ABAP name from IO_TECH_REQUEST_CONTEXT, or by the external name if you use IT_FILTER_SELECT_OPTIONS instead. Paging without ORDER BY returns unstable pages. Inside $batch changesets, Gateway rejects COMMIT WORK in the CRUD methods unless you implement deferred processing in CHANGESET_BEGIN and CHANGESET_END.

**Cta:** If you want people to ask questions of your SAP order data in plain English on your own servers, using services like this one as read-only tools, we can set that up.

**Faq:**

#### What are the steps to create an OData service in SAP?

**Answer:** In SEGW create a project, model the entity type and entity set, generate runtime objects, redefine the CRUD methods in the DPC_EXT class, activate, then register the service on the Gateway hub in /IWFND/MAINT_SERVICE with the right system alias. Test with /IWFND/GW_CLIENT and check /IWFND/ERROR_LOG if anything fails.

#### How do I write an SAP OData POST example in ABAP?

**Answer:** Redefine <entity set>_CREATE_ENTITY, call io_data_provider->read_entry_data( IMPORTING es_data = ls_entity ), validate, create the object with a BAPI and return the result in ER_ENTITY. Clients must send a CSRF token fetched with a prior GET, otherwise the POST fails with HTTP 403.

#### Why does $inlinecount return zero?

**Answer:** Gateway does not count for you in a custom GET_ENTITYSET. Check io_tech_request_context->has_inlinecount( ) and set es_response_context-inlinecount to the total number of matching rows, counted before paging. The generator does this with a separate SELECT COUNT(*) on the same WHERE clause.

#### Should I use SEGW or RAP for a new OData service?

**Answer:** On S/4HANA and recent ABAP platforms SAP recommends RAP with CDS views for new services, including OData V4. SEGW remains common on ECC, older NetWeaver Gateway hubs and for extending existing services. This generator is for the SEGW DPC_EXT model only.

## Search terms

odata services examples in sap abap, odata example in sap abap, steps to create odata service in sap, sap odata post example, odata in sap abap steps, how to create odata service in sap, dpc_ext get_entityset example, segw create_entity example

---
Talk to an engineer: https://netray.co/contact?intent=erp_ai | Machine catalog: https://netray.co/agent/catalog.json
