Appearance
Lesson 21 — Consuming SAP S/4HANA APIs with OData and Clean Core
Guided learning: 3 hours
Independent practice: 3 hours (separate file)
Environment: SAP BTP ABAP Environment Trial + Eclipse with ABAP Development Tools (ADT)
Before this lesson: HTTP Workshop — REST APIs with ABAP Cloud
In the HTTP Workshop, you sent HTTP requests and read JSON responses. In this lesson, you will call a real SAP S/4HANA Cloud OData API and learn how SAP can convert the response into typed ABAP data. You will also understand why working through a supported API is an important part of Clean Core.
This is a read-only lesson. You will not create, update, or delete data in the shared S/4HANA demonstration system.
Classroom setup note: The connection and OData proxy shown below were successfully tested in one SAP BTP ABAP Trial tenant using the object names shown in the code. Other Trial tenants and student namespaces must still be checked. If your generated object names differ, use the actual names displayed in your ADT project.
1. The business problem: product data is in another system
Imagine you are developing a purchasing application on SAP BTP. A user must select a product, but the company's product data already lives in SAP S/4HANA.
We should not maintain a second, independent copy of the product master data just for our application. Instead, our ABAP program can ask S/4HANA for the product information through an API.
text
Your ABAP program in SAP BTP
|
| Request: "Give me product data"
v
S/4HANA Product OData API
|
| Response: product IDs, types, groups and units
v
Your ABAP program displays the productsIn this lesson you will use two ways to call the same SAP API:
| Approach | What the program receives | What you learn |
|---|---|---|
| HTTP request (as in the workshop) | JSON text | What actually comes back from S/4HANA |
| OData Client Proxy generated from an SCM | ABAP internal table | How SAP makes OData services easier to consume |
Your finished result: A runnable ABAP class listing products such as A001, A002, B001, and their product types. Those identifiers appeared in a previously successful Trial test, but the records available in your tenant may differ.
2. What you need before opening the exercises
Confirm you have:
- Eclipse with the ABAP Development Tools (ADT) plugin.
- An open ABAP Cloud project connected to your BTP ABAP Trial system.
- Permission to create an ABAP package, class and Service Consumption Model.
- The existing outbound communication scenario
ZBTP_TRIAL_SAP_COM_0309in your Trial system for the shared S/4HANA Product API. - The ability to open links in your browser and download an
.edmxfile.
For our demonstrated classroom setup we use the following names. The suffix 001 is an example, not a reserved SAP value.
| Item | Working example |
|---|---|
| Development package | Your existing writable package, or ZPKG_L21_001 |
| Shared outbound communication scenario | ZBTP_TRIAL_SAP_COM_0309 |
| SAP OData V2 service | API_CLFN_PRODUCT_SRV |
| Service Consumption Model | ZSC_L21_PROD_001 |
| Generated class | ZSC_L21_PROD_001 (confirm in ADT) |
| Products entity set in generated proxy | A_CLFN_PRODUCT |
| Example proxy model version | 0001 |
Object-name rule: If you work with a different suffix, change it in the wizard and in every ABAP code reference. Do not change the SAP-provided communication scenario or remote API name.
Where can you find the API?
Open SAP Business Accelerator Hub — Product Master Data Including Classification (Read).
This is the documentation/download page, not the URL your ABAP program calls at runtime.
The actual OData service has this general URL form:
text
https://<S4HANA-HOST>/sap/opu/odata/sap/API_CLFN_PRODUCT_SRV/<S4HANA-HOST> is only a placeholder. Our communication arrangement already contains the configured connection and credentials. Do not hard-code a host name or password.
3. First: confirm that the connection works
You already know HTTP GET from the workshop. We will reuse that knowledge as a quick check before creating the Service Consumption Model.
Step 3.1 — Open the ABAP project and choose a package
- Open Eclipse.
- If the ABAP view is not visible, open Window → Perspective → Open Perspective → Other…, choose ABAP, and click Open.
- In Project Explorer, expand your BTP ABAP Trial project.
- Find an existing package where you can create ABAP objects.
- If you need a new package: right-click the
ZLOCALsoftware component or an allowed parent package and choose New → ABAP Package. EnterZPKG_L21_001(or your own unique name), accept the allowed package settings and finish. If your Trial project uses a different permitted package hierarchy, follow that hierarchy.
If you already have a writable package from the HTTP Workshop, reuse it. A new package is not required.
Step 3.2 — Create a console class
Right-click your writable package in Project Explorer.
Select New → ABAP Class. If the menu does not show it, select New → Other ABAP Repository Object…, type
Class, and select ABAP Class.Enter:
Wizard field Value Name ZCL_L21_HTTP_CHECK_001Description Check S4 Product API over HTTPIf the wizard has an Add Interface option, add
IF_OO_ADT_CLASSRUN(otherwise the source below includes it).Select a transport request if ADT requires one; in a local Trial package a request may not be required.
Click Finish.
In the class editor, replace the entire generated source with this code.
Step 3.3 — Paste the complete HTTP check class
abap
CLASS zcl_l21_http_check_001 DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_l21_http_check_001 IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
TRY.
out->write( '1. Finding the S/4HANA destination...' ).
"The destination contains the configured host and credentials.
DATA(lo_destination) =
cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'ZBTP_TRIAL_SAP_COM_0309'
).
DATA(lo_client) =
cl_web_http_client_manager=>create_by_http_destination(
i_destination = lo_destination
).
"Keep the OData service path already in the destination.
lo_client->enable_path_prefix( ).
DATA(lo_request) = lo_client->get_http_request( ).
"Request the Product entity set and only one record.
lo_request->set_uri_path(
i_uri_path = '/A_ClfnProduct'
).
lo_request->set_query(
query = '$top=1&$format=json'
).
out->write( '2. Sending HTTP GET...' ).
DATA(lo_response) = lo_client->execute(
i_method = if_web_http_client=>get
).
DATA(ls_status) = lo_response->get_status( ).
out->write( |HTTP status: { ls_status-code }| ).
DATA(lv_body) = lo_response->get_text( ).
IF ls_status-code = 200.
out->write( 'PASS: The remote API responded.' ).
ELSE.
out->write( 'CHECK: The API did not return HTTP 200.' ).
ENDIF.
"Limit the console output: the Product API has many fields.
IF strlen( lv_body ) > 600.
lv_body = substring(
val = lv_body
off = 0
len = 600
).
ENDIF.
out->write( 'Response preview (may be truncated):' ).
out->write( lv_body ).
CATCH cx_root INTO DATA(lx_error).
out->write( 'ERROR during the HTTP test:' ).
out->write( lx_error->get_text( ) ).
ENDTRY.
ENDMETHOD.
ENDCLASS.Step 3.4 — Activate and run
- Save the class using Ctrl+S.
- Activate it using Ctrl+F3, or the Activate button in the ADT toolbar.
- If the Problems view reports errors, double-click the error to jump to the relevant source line.
- With the class editor active, press F9 (Run As → ABAP Application (Console) if the context menu presents that option).
- Open the ABAP Console view if Eclipse does not show it automatically.
A successful response will resemble:
text
1. Finding the S/4HANA destination...
2. Sending HTTP GET...
HTTP status: 200
PASS: The remote API responded.
Response preview (may be truncated):
{"d":{"results":[{"__metadata": ... "Product":"A001" ...The displayed JSON excerpt is intentionally truncated. It is a preview, not guaranteed to be a complete JSON document.
Checkpoint: Do you have HTTP 200 and a response containing a product? If yes, the remote connection is working. This does not yet test the Service Consumption Model.
If not, go to Section 12 — Troubleshooting before proceeding.
4. Understand what the Service Consumption Model is for
Your first class works, but the API returned JSON text. To apply business logic to each product you would normally need to interpret that text and map it into ABAP structures.
For OData services, SAP offers an easier approach:
- SAP publishes an EDMX metadata file describing the API: entity sets, fields, types and relationships.
- You import that file into an ADT Service Consumption Model (SCM).
- ADT generates a class containing ABAP types and information about the remote service.
- Your program uses an OData Client Proxy to request data using the model.
- The proxy converts the response into a typed ABAP internal table.
text
EDMX metadata (API description, no live product records)
|
v
Service Consumption Model (created in Eclipse ADT)
|
v
Generated ABAP class (types and service model)
|
v
OData Client Proxy (makes the HTTP/OData request)
|
v
ABAP internal table (Product, ProductType, ProductGroup ...)Important distinction: Creating and activating the SCM does not fetch products. Products are fetched only when your ABAP program executes the request.
5. Download the OData EDMX file
Step 5.1 — Open the official API page
In your browser, open:
https://api.sap.com/api/API_CLFN_PRODUCT_SRV/overview
This is SAP Business Accelerator Hub. If a login is needed to download the specification, sign in with the account permitted for your training setup.
Step 5.2 — Find the specification
Open the API Specification tab on the API's page.
Locate the OData EDMX file/download option.
Download the file to your computer.
Keep its name if possible:
API_CLFN_PRODUCT_SRV.edmxNote the folder where your browser saved it (for example, Downloads).
Checkpoint: The file extension should be .edmx. If you open it in a text editor, it should contain XML metadata. Do not select a JSON response, an image, or a web-page shortcut as the metadata file.
If you cannot download from the Hub
Use the download option in the SAP Business Accelerator Hub API Specification interface or ask for the matching Product API EDMX already downloaded for your class. An EDMX is a specification; do not use the truncated JSON from Section 3. You can also obtain metadata from a properly authorized service $metadata endpoint, but that generally needs credentials and is not required here.
6. Create the Service Consumption Model in Eclipse ADT
Follow these steps carefully. The screens are part of the ADT wizard; menu text may differ slightly between plugin versions.
Step 6.1 — Start the wizard
- Return to Eclipse → Project Explorer.
- Expand your ABAP project.
- Right-click the same writable package used for your HTTP check class.
- Choose New → Other ABAP Repository Object….
- In the search field, type Service Consumption Model (typing just
Servicealso works). - Select Service Consumption Model.
- Click Next.
Do not select: Service Definition, Service Binding, or Service Consumption Model for another protocol. Those are different objects.
Step 6.2 — Name your model
On New Service Consumption Model, enter:
| Field | Enter |
|---|---|
| Name | ZSC_L21_PROD_001 |
| Description | S4HANA Product API |
| Remote Consumption Mode | OData |
Then click Next.
If ZSC_L21_PROD_001 already exists in the package from a previous attempt, reuse it if active and correct. Otherwise, choose a new unique name and carry that name into the ABAP code.
Step 6.3 — Import the EDMX
- On the Service Metadata File page, click Browse….
- Locate
API_CLFN_PRODUCT_SRV.edmxin your Downloads folder (or wherever you saved it). - Select it and confirm.
- Find the Class Name field.
- For this classroom example, use the suggested name
ZSC_L21_PROD_001, if the wizard accepts it. The generated class name may differ; record the actual value. - Click Next.
The Service Consumption Model and the generated class are related but not the same repository object.
Step 6.4 — Inspect the entities
The Components of OData Service page displays imported entity sets/types.
Locate the Product entity, for example:
text
Entity set: A_ClfnProduct
Entity type: A_ClfnProductTypeYou may also find A_ProductDescription and other entities.
Do not manually recreate these as database tables or CDS views. They describe data exposed by the remote API.
Click Next.
Step 6.5 — ETag support
If an ETag Support page appears, leave it at the default/unselected settings for this read-only example and click Next.
ETags are mainly relevant to concurrency and updates; this lesson only reads data.
Step 6.6 — Finish the wizard
- Review the summary/transport page.
- Choose an allowed transport if your system requires one. In some Trial packages, none is needed.
- Click Finish.
- Return to Project Explorer.
- Press F5 on your package if the objects are not immediately visible.
You should now have:
- Service Consumption Model:
ZSC_L21_PROD_001 - Generated ABAP class: often also
ZSC_L21_PROD_001(use the actual name in your system)
Step 6.7 — Activate
- Double-click the Service Consumption Model.
- Press Ctrl+F3 to activate it.
- Inspect the Problems view for errors.
- If activation requires the generated class, open it and activate the required objects.
Checkpoint: The SCM and its generated ABAP class are visible and active, without unresolved activation errors.
7. Find the exact identifiers generated by your SCM
Before copying code into a new class, inspect the objects ADT actually generated. This prevents many avoidable syntax and runtime errors.
Step 7.1 — Open the model's Read List example
- In Project Explorer, double-click
ZSC_L21_PROD_001(Service Consumption Model). - Find the entity
A_ClfnProductin the SCM editor. - Select the Read List operation.
- Find the generated ABAP sample/code pane.
- Click Copy to Clipboard if offered, and paste the sample into a temporary text editor for reference.
This is sample code, not a runnable class: the generated example usually includes placeholders for the HTTP client, destination and relative service root.
Step 7.2 — Record your Model Passport
Write these values from your own SCM/editor:
| Detail | Example from the verified setup | Where to check |
|---|---|---|
| SCM/model ID | ZSC_L21_PROD_001 | SCM name and proxy_model_id |
| Repository ID | DEFAULT | Read List snippet |
| Proxy model version | 0001 | Read List snippet |
| Entity set ID | A_CLFN_PRODUCT | create_resource_for_entity_set |
| Generated class | ZSC_L21_PROD_001 | Project Explorer |
| Product row type | tys_a_clfn_product_type | Generated class / snippet |
Very important: A_ClfnProduct is the human-readable entity name in metadata. A_CLFN_PRODUCT is the ABAP proxy identifier used in our generated Read List sample. They may not have identical capitalization or underscores.
Step 7.3 — Find the generated ABAP type
Open the generated class in Project Explorer.
Look in the public TYPES declarations.
Search for
tys_a_clfn_product_typeusing Ctrl+F.Inspect the component fields, for example:
textproduct product_type product_group base_unitRecord the exact row type shown in your class. We will declare an internal table using it.
Checkpoint: You can point to your generated class and identify one row type and at least three fields. If the type name differs, change its reference in the code that follows.
8. Create an OData client proxy program: the full class
Now we will retrieve the same products, but as ABAP structures instead of raw JSON.
Step 8.1 — Create the class in Eclipse
In Project Explorer, right-click your Lesson 21 package.
Choose New → ABAP Class (or New → Other ABAP Repository Object… → ABAP Class).
Enter:
Field Value Name ZCL_L21_PRODUCT_PROXY_001Description Read S4 products using OData proxyIf offered, add interface
IF_OO_ADT_CLASSRUN. It also appears in the source below.Click Finish, then replace the entire generated source.
Step 8.2 — Paste this complete class
The code uses the exact Service Consumption Model and row type from the previously successful Trial test. Change only your own model and class names if they differ.
abap
CLASS zcl_l21_product_proxy_001 DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_l21_product_proxy_001 IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
"The generated SCM row type represents one remote product.
DATA lt_products TYPE TABLE OF
zsc_l21_prod_001=>tys_a_clfn_product_type.
TRY.
"1. Resolve the existing S/4HANA connection.
DATA(lo_destination) =
cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'ZBTP_TRIAL_SAP_COM_0309'
).
"2. Construct the underlying HTTP client.
DATA(lo_http_client) =
cl_web_http_client_manager=>create_by_http_destination(
i_destination = lo_destination
).
"3. Use your generated model for an OData V2 proxy.
DATA(lo_proxy) =
/iwbep/cl_cp_factory_remote=>create_v2_remote_proxy(
is_proxy_model_key = VALUE #(
repository_id = 'DEFAULT'
proxy_model_id = 'ZSC_L21_PROD_001'
proxy_model_version = '0001'
)
io_http_client = lo_http_client
iv_relative_service_root = ''
).
"The destination already points to the service root.
"Do not add that service path a second time.
"4. Request a list from the Product entity set.
DATA(lo_request) =
lo_proxy->create_resource_for_entity_set(
'A_CLFN_PRODUCT'
)->create_request_for_read( ).
"5. Retrieve at most five products.
lo_request->set_top( 5 ).
"6. Execute the remote API call.
DATA(lo_response) = lo_request->execute( ).
"7. Convert the response into typed ABAP rows.
lo_response->get_business_data(
IMPORTING
et_business_data = lt_products
).
"8. Display a short, readable result.
out->write( 'S/4HANA products via OData proxy' ).
out->write( |Products returned: { lines( lt_products ) }| ).
IF lt_products IS INITIAL.
out->write( 'The API returned no matching products.' ).
ELSE.
LOOP AT lt_products INTO DATA(ls_product).
out->write(
|Product: { ls_product-product } | &&
|Type: { ls_product-product_type } | &&
|Group: { ls_product-product_group } | &&
|Unit: { ls_product-base_unit }|
).
ENDLOOP.
ENDIF.
CATCH cx_root INTO DATA(lx_error).
out->write( 'ERROR calling the OData Product API:' ).
out->write( lx_error->get_text( ) ).
ENDTRY.
ENDMETHOD.
ENDCLASS.Step 8.3 — Activate and run
- Press Ctrl+S to save.
- Press Ctrl+F3 to activate.
- If you see an error on
zsc_l21_prod_001, check the generated class name from Section 7. - If you see an error on
tys_a_clfn_product_type, check the row type from Section 7. - If activation succeeds, press F9 to run the ABAP console application.
- Inspect the console output.
A successful output might be:
text
S/4HANA products via OData proxy
Products returned: 5
Product: A001 Type: SERV Group: A001 Unit: AU
Product: A002 Type: SERV Group: A002 Unit: AU
Product: B001 Type: SERV Group: B001 Unit: AU
Product: B002 Type: SERV Group: B002 Unit: AU
Product: B003 Type: SERV Group: B003 Unit: AUThese example values were observed in a previous successful Trial call. They are not a promise that every tenant or run will return the same first five records. Without a requested sort order, the returned order is not guaranteed.
Checkpoint: You have retrieved remote product records as a typed ABAP internal table, without writing a JSON parser.
What each line is doing
| ABAP code | Meaning |
|---|---|
create_by_comm_arrangement | Uses the existing outbound connection and credentials |
create_by_http_destination | Creates the HTTP client that sends the request |
create_v2_remote_proxy | Creates the OData V2 client proxy from SCM metadata |
create_resource_for_entity_set | Chooses which collection to read |
set_top( 5 ) | Limits the number of returned rows |
execute( ) | Contacts the remote API |
get_business_data( ) | Places the response into your typed ABAP table |
LOOP AT | Reads the familiar ABAP fields in that table |
9. Filter the results on the S/4HANA server
The first program asked for any five products. In a real application, users usually need specific products.
Instead of downloading everything and filtering locally, the OData client proxy can send a filter to the API. We will request the product A001, which existed in our tested demonstration system.
Step 9.1 — Create a second test class
- Right-click the same package → New → ABAP Class.
- Name it
ZCL_L21_FILTER_001. - Description:
Filter remote Product API. - Click Finish and replace the complete source.
Step 9.2 — Paste the complete filtered example
abap
CLASS zcl_l21_filter_001 DEFINITION
PUBLIC
FINAL
CREATE PUBLIC.
PUBLIC SECTION.
INTERFACES if_oo_adt_classrun.
ENDCLASS.
CLASS zcl_l21_filter_001 IMPLEMENTATION.
METHOD if_oo_adt_classrun~main.
DATA lt_products TYPE TABLE OF
zsc_l21_prod_001=>tys_a_clfn_product_type.
"A range represents the condition Product = 'A001'.
DATA lt_product_range TYPE if_rap_query_filter=>tt_range_option.
lt_product_range = VALUE #(
( sign = 'I' option = 'EQ' low = 'A001' )
).
TRY.
DATA(lo_destination) =
cl_http_destination_provider=>create_by_comm_arrangement(
comm_scenario = 'ZBTP_TRIAL_SAP_COM_0309'
).
DATA(lo_http_client) =
cl_web_http_client_manager=>create_by_http_destination(
i_destination = lo_destination
).
DATA(lo_proxy) =
/iwbep/cl_cp_factory_remote=>create_v2_remote_proxy(
is_proxy_model_key = VALUE #(
repository_id = 'DEFAULT'
proxy_model_id = 'ZSC_L21_PROD_001'
proxy_model_version = '0001'
)
io_http_client = lo_http_client
iv_relative_service_root = ''
).
DATA(lo_request) =
lo_proxy->create_resource_for_entity_set(
'A_CLFN_PRODUCT'
)->create_request_for_read( ).
"Build a remote OData filter from the range.
DATA(lo_filter) =
lo_request->create_filter_factory( )->create_by_range(
iv_property_path = 'PRODUCT'
it_range = lt_product_range
).
lo_request->set_filter( lo_filter ).
lo_request->set_top( 5 ).
DATA(lo_response) = lo_request->execute( ).
lo_response->get_business_data(
IMPORTING
et_business_data = lt_products
).
out->write( |Matching products: { lines( lt_products ) }| ).
IF lt_products IS INITIAL.
out->write( 'No product matched this filter.' ).
ELSE.
LOOP AT lt_products INTO DATA(ls_product).
out->write(
|{ ls_product-product } - { ls_product-product_type }|
).
ENDLOOP.
ENDIF.
CATCH cx_root INTO DATA(lx_error).
out->write( 'API or connection error:' ).
out->write( lx_error->get_text( ) ).
ENDTRY.
ENDMETHOD.
ENDCLASS.Step 9.3 — Run two tests
- Activate (Ctrl+F3) and execute (F9).
- Check that the result contains only
A001if that product exists in your remote backend. - Change
low = 'A001'tolow = 'ZZ_NONEXISTENT_L21'. - Activate and execute again.
- Expect zero matching records (if the API accepts that filter), not a connection error.
The last test illustrates an essential point: a successful call returning no rows is different from a failed call.
What was sent? The OData proxy translates the filter conceptually into something like $filter=Product eq 'A001', but your application code does not need to write the URL encoding itself.
10. How this connects to Clean Core
So far, you have proved that a BTP application can read S/4HANA product data using a published OData API.
Clean Core means keeping standard SAP software as upgrade-safe as possible: avoid modifications and unsupported dependencies, and use suitable released extension points and interfaces.
Here is today's design decision:
| Approach | Assessment |
|---|---|
| Read an S/4HANA internal database table directly | Not our supported integration approach; tightly couples the application to internals |
| Call the documented Product API | The intended remote integration interface for this exercise |
| Hard-code a backend host/password in the class | Avoid; use approved connection configuration |
| Build an SCM and OData client proxy | Helps consume the remote OData interface with typed ABAP data |
Three release-contract terms you should recognize
- C0 — Extend: a released extension point that can be extended in the permitted way.
- C1 — Use System-Internally: a released API for use inside the relevant ABAP system.
- C2 — Use as Remote API: a contract for an API intended for remote consumption.
These are different release contracts, not three versions of OData. A remote Product API does not become C1 simply because you called it from ABAP. For external systems, always verify the specific API's documentation, supported operations and applicable release contract. This lesson concentrates on the integration part of Clean Core, not every Clean Core dimension.
Think about it: Why is it easier to replace or upgrade an S/4HANA implementation when your external application depends on a published API rather than internal database tables?
11. Compare the two approaches
| Question | Direct HTTP call | Service Consumption Model + OData Proxy |
|---|---|---|
| Uses an HTTP connection? | Yes | Yes, underneath |
| Needs EDMX to build our example? | No | Yes, to generate the SCM model |
| What does your code receive? | JSON text | Typed ABAP structures/table |
| Does the API keep ownership of the data? | Yes | Yes |
| Can the program filter results? | Yes, by constructing query options | Yes, using the proxy's request/filter methods |
| Is it suitable for every REST/JSON API? | Generic HTTP is more flexible | Only when the API is compatible with the supported OData model |
You have not created a new SAP S/4HANA service, and you have not copied product master data into your BTP database. You are a consumer of an existing remote API.
12. Troubleshooting: find the failure point
Do not make random changes to the URL or regenerate the model before identifying what failed.
| Problem | What to check |
|---|---|
| Cannot find Service Consumption Model in New wizard | Confirm you are using Eclipse ADT and an ABAP Cloud project, not a general Java perspective; check plugin version/permissions |
| EDMX file rejected | Confirm you selected a valid .edmx XML metadata document for API_CLFN_PRODUCT_SRV, not the Hub page or JSON |
| Class name / type is unknown | Open the generated class and Read List sample; replace the example name with the actual name in your project |
proxy_model_id unknown | Copy the model ID and version from the generated Read List example |
Unknown A_CLFN_PRODUCT entity set | Check the generated entity-set identifier in the SCM sample, not the display label |
| HTTP 401 / 403 | The remote call was refused; check permission/authentication in the configured arrangement (do not insert credentials into source) |
| HTTP 404 | Verify the destination service root and whether an extra service path was added |
create_by_comm_arrangement fails | Confirm the shared Trial scenario is present in this tenant and available to the developer |
Exception in execute( ) | Inspect the exception text; the proxy was created, but execution failed remotely or during response handling |
| Zero records | Verify filter and data availability; zero records is not necessarily an error |
| Unexpected product order | set_top() alone does not guarantee a stable sort order |
How to read an ADT activation error
- Open the Problems view from Window → Show View → Other… → General → Problems if it is hidden.
- Double-click the error.
- Check which identifier is underlined.
- Compare it with the Model Passport in Section 7.
- Activate again before running. Do not attempt to run a class that failed activation.
If the Trial connection is unavailable
The SCM can still be discussed and, when the wizard is available, generated from the EDMX without calling the remote backend. For a runnable local-data fallback, use the complete separate class in the Companion. A local simulation does not prove the remote API works. Mark your evidence clearly as either LIVE S/4HANA or LOCAL SIMULATION.
13. What you should now be able to do
If connectivity is unavailable, complete the conceptual and model-generation items that your environment supports, run the Companion's local fallback, and record the real restriction. Mark the live-only items below as not executed until remote access is restored. Use the separate offline submission checklist in the Practice.
Next: Complete Lesson 21 — Independent Practice. You will apply the same skills to different lookup requirements without repeating every guided instruction.
14. Useful URLs
Use these links for this lesson. You do not need to complete an outside workshop.
- API documentation + EDMX download: https://api.sap.com/api/API_CLFN_PRODUCT_SRV/overview
- SAP Developer — Creating an outbound OData call and SCM: https://developers.sap.com/tutorials/abap-environment-business-partner-outbound-call
- SAP Help — Preparing access to a remote OData service (SCM wizard): https://help.sap.com/docs/abap-cloud/abap-rap/preparing-access-to-remote-odata-service
- SAP Help — Creating a remote client proxy: https://help.sap.com/docs/abap-cloud/abap-rap/creating-remote-client-proxy
- SAP Help — Developing UI services with remote access: https://help.sap.com/docs/abap-cloud/abap-rap/developing-ui-service-with-access-to-remote-service
- SAP Help — HTTP outbound services and path prefixes: https://help.sap.com/docs/abap-cloud/abap-integration-connectivity/outbound-service
Technical verification boundary: The connection, product proxy model, product row type and five-product output are based on a previously successful test in a BTP ABAP Trial tenant. The new filtered class is based on SAP's documented client-proxy filter pattern; it still needs activation/execution in your own tenant.