Skip to content

Lesson 23 Companion — Side-by-Side Extension Reference ​

Use with: Lesson 23 Guided Content + Independent Practice
Environment: SAP BTP ABAP Trial, Eclipse ADT, Fiori Elements Preview

1. What is a side-by-side extension? ​

A side-by-side extension adds application features on SAP BTP while leaving SAP S/4HANA's standard business software unchanged. The extension can use published APIs to read information from or integrate with S/4HANA.

In this project:

  • SAP S/4HANA remains the owner of Product master data.
  • Your own BTP RAP business object owns Stock Check records.
  • The product value help reads real remote IDs through the OData client proxy.
  • Saving a Stock Check writes to your own BTP table only.

Stock check vs stock posting: Saving CountedQty = 8 does not change a real SAP warehouse stock balance. Making an inventory posting would require an explicitly supported, authorized S/4HANA API and a different business design. This project deliberately does not attempt that operation.

2. Architecture: trace one user interaction ​

text
User opens Fiori Create Stock Check form
    |
    +-- ProductId value help icon clicked
    |       |
    |       v
    |   OData V4 Product entity (BTP)
    |       |
    |       v
    |   ZCE_L23_PROD_##  (CDS Custom Entity)
    |       |
    |       v
    |   ZCL_L23_PRODUCTS_## (IF_RAP_QUERY_PROVIDER)
    |       |
    |       v
    |   New Product OData V2 SCM + destination (created here)
    |       |
    |       v
    |   SAP S/4HANA Product API (read-only)
    |
    +-- User chooses Product and clicks Create/Save
            |
            v
        Managed StockCheck RAP BO
            |
            v
        ZL23_STOCK_## (BTP local database)

Two separate OData layers: The app exposes an OData V4 UI service on BTP, and it consumes an OData V2 Product API in the remote S/4HANA system. The two versions are not interchangeable; the query provider acts as the bridge.

3. Which objects do what? ​

ObjectCreated byResponsibility
ZL23_STOCK_##YouLocal persistent Stock Check rows
ZI_L23_STOCK_##RAP generatorManaged BO root CDS data model
ZBP_I_L23_STOCK_##RAP generatorBehavior implementation class
Draft table ZL23_STKD_##RAP generatorLocal transactional draft state
ZC_L23_STOCK_##RAP generatorUI-facing projection; place value-help annotation here
ZUI_L23_STOCK_##RAP generator, then you updateExposes StockCheck and Product
ZUI_L23_STOCK_O4_##RAP generatorOData V4 UI service binding
ZCE_L23_PROD_##YouThree-field CDS custom entity for remote Product data
ZCL_L23_PRODUCTS_##YouImplements remote query using IF_RAP_QUERY_PROVIDER; declares matching output row fields locally
ZCX_L23_QUERY_##YouReports query failure through RAP query exception handling
ZSC_L23_PROD_##You create it in this lessonMetadata and generated ABAP types for remote OData V2
ZBTP_TRIAL_SAP_COM_0309BTP Trial configurationShared S/4HANA outbound connection

Replace every ## with your TWO uppercase initials (for example, AB) before creating or activating a student object. These are example names; the generator may choose different names depending on your wizard entries. Copy actual names from your ADT package if they differ.

4. Why use the RAP generator here? ​

The project assumes basic familiarity with tables, CDS, behavior definitions, projections and service bindings; the guided file supplies the actual Eclipse steps. Rewriting all that boilerplate manually would take much of the final course day.

SAP's Generate ABAP Repository Objects → OData UI Service wizard generates the ordinary managed RAP application from your local database table. Your main new skill is integrating remote reference data with that app. https://developers.sap.com/tutorials/abap-environment-rap100-generate-ui-service

Generated source is still real code. Open and inspect the BDEF, CDS root, projection and service definition so you understand the objects the generator created. Never assume the generator has added your application's business validations or authorization policy.

5. What is a CDS Custom Entity? ​

A CDS Custom Entity describes a readable data shape whose rows do not come directly from ABAP SQL in the same way as a normal CDS view entity. Its query is implemented by an ABAP class:

abap
@ObjectModel.query.implementedBy: 'ABAP:ZCL_L23_PRODUCTS_##'
define custom entity ZCE_L23_PROD_##
{
  key Product         : abap.char(40);
  ProductTypeName     : abap.char(4);
  ProductGroupName    : abap.char(9);
}

It does not create a database table. It is not a transactional RAP Business Object. It is a query resource that a Fiori value help can use.

This is the supported pattern when the data must come from another service via an OData Client Proxy. https://help.sap.com/docs/abap-cloud/abap-rap/using-cds-custom-entity-for-data-modeling

6. Why is the query-provider class necessary? ​

A Fiori value-help dialog sends a request such as:

text
Read Products
Filter Product by user selection
Return page 1 (top 20)
Include total matching count

IF_RAP_QUERY_PROVIDER~SELECT receives that request. It is your job to translate the request into an OData V2 call and return valid data.

Essential query responsibilities ​

Incoming informationABAP sourceHow it is handled
Filtersio_request->get_filter( )->get_as_ranges( )Map local property names to Product API property names and build OData filter nodes
Page size and offsetio_request->get_paging( )Call remote set_top() and set_skip()
Count requested?is_total_numb_of_rec_requested( )Request the remote count and return the total matching count, not the page length
Data requested?is_data_requested( )Fetch and map typed Product rows only when needed
Stable orderingget_sort_elements( ) + set_orderby( )Honor supported sorting and append Product as a stable tie-breaker
ErrorRAP query exceptionDo not report an HTTP/SCM failure as zero matching products

Avoid a common bug: lines( lt_products ) is only the number of rows on the returned page, not the total number of products in the remote service. Passing it as set_total_number_of_records() breaks Fiori paging. The guided implementation requests the remote count from the proxy and returns that count.

For a production UI, implement additional $orderby fields, search expressions and complex filters or reject them explicitly; never silently ignore requested behavior. The guided provider maps requested sorting on Product, Product Type, and Product Group, and appends Product as a stable tie-breaker. It rejects unsupported search, filter, sort and unlimited paging rather than silently ignoring them.

7. Remote property mappings ​

Your custom entity's field names are chosen for the UI; the remote SCM uses different technical property paths:

UI Custom Entity fieldOData Client Proxy propertyGenerated ABAP field
ProductPRODUCTproduct
ProductTypeNamePRODUCT_TYPEproduct_type
ProductGroupNamePRODUCT_GROUPproduct_group

Never guess generated names if your model differs. Open the SCM you created in this lesson → select A_ClfnProduct → Read List. Confirm the entity set and model key, then inspect the generated class types.

Why avoid calling the custom field ProductType? Using a distinct name helps students differentiate the new local data model from the remote API property, and matches the proven SAP custom-entity teaching pattern.

8. The value-help annotation ​

The annotation belongs on the stock-check projection field corresponding to product_id:

abap
@Consumption.valueHelpDefinition: [
  { entity: { name: 'ZCE_L23_PROD_##', element: 'Product' },
    useForValidation: false }
]
ProductId,

The referenced entity must also be exposed in the same service definition:

abap
expose ZCE_L23_PROD_## as Product;

In this course useForValidation: false leaves value-help-based frontend input validation disabled while still letting users select remote Product IDs. Setting it to true would enable the Fiori input check against the value help; it would not implement server-side validation inside your managed BO. Enforcing valid Product IDs for all callers, including alternative OData consumers and background processing, requires a separate RAP business validation. A production solution must also decide what that validation should do when S/4HANA is unavailable.

9. Generated RAP: field names and UI behavior ​

When you use the generator, inspect the created projection to find the exact alias for the database column product_id. It will commonly be ProductId, but the source is authoritative.

Similarly, the generated Fiori app might use draft editing. To create a permanent row, you may need to click Create inside the object page and later Save, depending on the draft state and UI version. Do not conclude that persistence failed just because a row is still in draft.

When testing, create one Stock Check with ProductId manually before adding remote value help. This isolates the local application from remote connection problems.

10. Why this supports Clean Core ​

DecisionBenefit
Write your new business-process records to a BTP tableAvoid changing S/4HANA standard persistence
Read master Product data from a documented S/4HANA APIDepend on a supported remote interface instead of private internals
Keep destination and credentials in an approved communication arrangementAvoid embedding backend URL/password in business logic
Build a Fiori UI service over managed RAPReuse SAP's transactional framework for local records

Clean Core is not simply 'using OData'. The contract and correct extension boundary matter. Not every remotely callable endpoint is released or supported.

11. Troubleshooting ladder (debug in this order) ​

  1. Does the new ZCL_L23_API_TEST_## console return products? If no, resolve the destination/API first.
  2. Does the generated local RAP Stock Check app save manually entered data? If no, resolve table/generator/draft first.
  3. Does ZCE_L23_PROD_## activate? Check annotation and query-provider interface implementation.
  4. Does the query provider activate? Check generated SCM class name, model ID/version, filter node types and exception class.
  5. Is Product exposed in the service definition? Check source and binding refresh.
  6. Is the value-help annotation on the projection field? Confirm actual ProductId field.
  7. Does the value-help dialog open but show no data? Check query execution, count, paging, filters and remote API response.
  8. Can the UI select a product but not save the stock-check record? This is a local RAP issue; debug the generated behavior/draft separately.

Remote connection unavailable ​

Your final-day project has two independent achievements. If the remote API is temporarily unavailable, demonstrate the working local RAP/Fiori application and document the blocked remote path. Do not claim the manually typed product is a remote value-help result.

12. Production considerations (outside today's coding scope) ​

The classroom project is a useful functional proof of concept, not a deploy-ready warehouse solution. A production version needs, among other things:

  • Authorization for local Stock Checks and remote Product reads. CDS custom entities do not automatically inherit normal CDS access control; the query implementation must enforce appropriate access policy.
  • Remote errors and resilience, including clear messages and fallback behavior if the external service cannot be reached.
  • Full query semantics if the value-help UI supports search, arbitrary sorting, complex filters or unbounded requests.
  • Data correctness for quantities, mandatory fields, status transitions and product validity. A UI value help alone is insufficient.
  • Lifecycle and monitoring, including operational logs, API/version compatibility, service limits and API performance.

13. Review questions ​

  1. Why does a stock-check record live in BTP instead of the S/4HANA Product API?
  2. What is the difference between a CDS Custom Entity and a CDS projection view?
  3. Why does the Fiori Product value help call IF_RAP_QUERY_PROVIDER?
  4. Why must you send count and paging information correctly?
  5. Why are there both OData V2 and OData V4 services in this project?
  6. Why does a value help not guarantee that every server-side write has a valid Product ID?
  7. Which specific part of the architecture helps maintain Clean Core?

Verification note: SAP documents the ADT generator, SCM creation, custom entities, query provider and remote client proxy methods. The assembled Lesson 23 project and new ZSC_L23_PROD_## model have not been activated or executed in your tenant during this revision. Use the guided checkpoints to validate each component before the final demonstration.