Appearance
Lesson 21 — Independent Practice: S/4HANA Product Lookup
Independent practice: 3 hours
Environment: SAP BTP ABAP Trial + Eclipse ADT
Prerequisite: Guided Lesson 21 — Consuming SAP S/4HANA APIs with OData and Clean Core
You have used direct HTTP and an OData Client Proxy to read product records from SAP S/4HANA. Now you will respond to a small development request using the same read-only Product API, but without being given the final implementation line by line.
No assessment timer and no per-chapter time limits. Work through the tasks in order and verify your results.
1. Your development request
A purchasing colleague needs a tool to answer these questions:
“Can I look up a particular product ID? Can I search for products of a specific type? Can I see a short list without being overwhelmed by dozens of empty fields? And can you tell me the difference between a valid search with no matches and a broken connection?”
Build an ABAP Console Product Lookup that sends OData read requests to the Product API and displays clear results.
You must not update products in the shared S/4HANA system.
Deliverables
The table below describes the live S/4HANA route. If the connection is unavailable, use the offline evidence requirements in Sections 9–10 and mark remote tests as not executed.
| Item | What you will submit |
|---|---|
| Product lookup class | A runnable ABAP class using your SCM and IF_OO_ADT_CLASSRUN |
| Exact-ID filter | A run that looks up a known Product ID |
| Type filter | A run that queries ProductType using a server-side OData filter |
| Negative test | A successful request that returns zero matching products |
| Model Passport | Actual IDs/class/type names from your SCM in ADT |
| Technical handover | A short explanation of results and one Clean Core decision |
The expected outcome is correct behavior, not particular numbers or product descriptions. Demo records can differ.
2. Prepare your environment
Step 2.1 — Open your package
Open Eclipse and the ABAP perspective.
In Project Explorer, expand your BTP ABAP Trial project.
Locate the writable package used during the guided lesson.
Confirm the following objects are visible and active:
ZSC_L21_PROD_001(or your own SCM name)- the SCM's generated ABAP class
ZCL_L21_PRODUCT_PROXY_001(or your own earlier class)
If your guided exercise created a different package or suffix, continue using it. There is no need to duplicate the SCM.
Step 2.2 — Record your Model Passport
Open the SCM editor → A_ClfnProduct → Read List. Record the values used by your generated code.
text
My package:
My SCM:
My generated ABAP class:
Repository ID:
Proxy model ID:
Proxy model version:
Product entity-set identifier:
Product row type:Why this matters: a model generated in a different student namespace can have different ABAP object names even when it describes the same S/4HANA API.
3. Task A — Search for a specific product
Create a new class named ZCL_L21_LOOKUP_001 (or use your assigned suffix).
Exact ADT steps
- Right-click your package → New → ABAP Class.
- Enter name
ZCL_L21_LOOKUP_001. - Description:
Product lookup using OData. - Finish the wizard.
- Implement
IF_OO_ADT_CLASSRUNso you can run the class using F9.
Use your guided ZCL_L21_FILTER_001 as a reference, but build this solution in your own class.
Required behavior
- Connect using the existing communication scenario
ZBTP_TRIAL_SAP_COM_0309. - Create an OData V2 client proxy using your SCM model ID and version.
- Select the generated entity-set identifier for products (example
A_CLFN_PRODUCT). - Set a server-side Product equality filter for a record that exists in your environment (for the previous test,
A001was available). - Request at most five records.
- Print Product ID, Product Type and Product Group on separate, readable lines.
Acceptance check: The returned Product IDs all match the requested exact ID; no unrelated products appear.
A useful code reference: the range
abap
DATA lt_range TYPE if_rap_query_filter=>tt_range_option.
lt_range = VALUE #(
( sign = 'I' option = 'EQ' low = 'A001' )
).This is not a complete program. You must create the request, generate the filter via create_filter_factory( ), execute it and handle the response. The guided lesson's complete filter class shows the correct sequence.
4. Task B — Search by product type
Extend or create a new version of your lookup class to answer:
“Show me up to three products whose product type is
SERV.”
Steps
- Locate the filter creation in your class.
- Change the property path to the generated identifier for
ProductType. In our working model this isPRODUCT_TYPE. - Change the filter value to
SERV. - Change the maximum result limit to
3. - Activate and execute the class.
- Print Product ID and Product Type for every result.
Example of the filter inputs:
abap
DATA lt_type_range TYPE if_rap_query_filter=>tt_range_option.
lt_type_range = VALUE #(
( sign = 'I' option = 'EQ' low = 'SERV' )
).Then set:
abap
iv_property_path = 'PRODUCT_TYPE'Acceptance check: You receive at most three products and every returned Product Type is SERV. If no products match, display an informative empty-result message instead of pretending that the API failed.
Question
Why is applying a filter on the S/4HANA server more useful than downloading hundreds of products and running DELETE lt_products WHERE ... locally?
5. Task C — Demonstrate an empty-result case
Return to the Product ID equality filter from Task A. If you reused the same class for Task B, change iv_property_path back from PRODUCT_TYPE to PRODUCT, keep option = 'EQ', and attach the Product ID range to this filter. This request should filter only by Product ID, without the earlier product-type condition.
Change the exact Product ID filter to a deliberately unlikely identifier, for example:
text
ZZ_NONEXISTENT_L21Activate and execute again.
Expected behavior: The remote call should complete successfully but the returned internal table should be empty. Your output should say something like:
text
Matching products: 0
No product matched this filter.If your backend returns an API error instead, record the actual response and investigate its cause. Do not claim an empty-result test passed when it did not.
Answer: What is the difference between 0 results, HTTP 404, and an exception while creating the communication destination?
6. Task D — Observe and handle a failure safely
Without modifying shared configuration or inventing credentials, inspect your code and locate where errors could occur:
- Creating the destination.
- Creating the OData proxy.
- Executing the request.
- Converting the response.
Verify your class catches exceptions and prints an understandable error message.
For example, include an error branch like:
abap
CATCH cx_root INTO DATA(lx_error).
out->write( 'Unable to retrieve product data:' ).
out->write( lx_error->get_text( ) ).This is appropriate for a small classroom test; business applications should classify expected exception types and provide structured diagnostics rather than treating all errors identically.
Do not change the actual communication arrangement, insert real passwords into source code, or attempt a write operation on the shared demonstration backend just to produce a failure.
7. Optional extension — Product descriptions
If your imported EDMX/SCM exposes the A_ProductDescription entity set, explore it. This is an optional extension, not a prerequisite for completing the core exercise.
- Open the SCM editor.
- Find
A_ProductDescriptionand choose Read List. - Copy the generated snippet into a temporary file.
- Record the exact entity-set proxy identifier, generated row type and property names; do not guess them.
- Create a new console class by adapting the same connection/proxy pattern.
- Read up to five description records.
- Display Product, Language, and ProductDescription, if those generated fields exist under those names.
- If the backend returns no text records, report that accurately; no records is not proof of incorrect code.
Consider filtering by language using the property name from the generated model. Language codes and available descriptions depend on the backend data.
This is how you investigate a new collection on an existing OData service without creating a new Service Consumption Model.
8. Clean Core decision
A colleague suggests the following solution:
“Why call an API? Why don't we just read the S/4HANA internal product table directly?”
Write a short response answering:
- Which system owns the Product master data?
- Why is a published API a better integration boundary?
- What does the communication arrangement provide?
- What did the Service Consumption Model generate that was not present in our raw HTTP code?
- What must be verified before assuming a remote API is suitable for production use?
Your answer should be understandable to a junior developer who has not used the SCM wizard before.
9. If your Trial tenant cannot reach S/4HANA
Do not invent success screenshots. A remote failure does not make the local ABAP lesson meaningless, but it changes what you can claim you tested.
Follow this sequence:
- Run the guided
ZCL_L21_HTTP_CHECK_001class again and record the exception or HTTP status. - Confirm whether your SCM generated the ABAP types and Read List samples successfully.
- If remote access fails, run the complete local fallback class in the Companion, and identify its output as LOCAL SIMULATION. With the supplied data and
SERVcondition, verify that it printsDEMO-001 - SERVandDEMO-002 - SERV, excluding theFERTrow. - Submit the SCM Model Passport using the artifacts you could generate. If metadata import or SCM generation is also blocked, mark those entries not generated and record the exact restriction; do not guess the identifiers.
- Explain from your lookup source where the Product ID filter, Product Type filter, result limit, and remote execution would run. Record remote tests that could not execute as not executed — connection unavailable, and attach the actual failure from step 1 separately.
Important: Local simulation demonstrates ABAP data handling only. It does not count as a successful S/4HANA API call or prove the client proxy works remotely.
10. Submission checklist
Complete the common checklist and the checklist for the route you actually used.
For both routes
Live S/4HANA route
If a live test fails or the backend rejects it, record the actual error and leave that test unpassed. A documented restriction explains incomplete verification; it is not a successful result.
Offline route
11. Technical handover template
Complete this short report in your own words. For an unexecuted remote test, enter not executed and the reason; do not put simulated rows in its result fields. Record local output in the separate simulation section.
text
Product Lookup — Technical Handover
Route: LIVE S/4HANA or OFFLINE
ABAP class:
SCM/model ID:
Generated proxy class:
Communication scenario:
Test 1 — Product ID filter:
Status: passed / failed / not executed
Input:
Result count:
Example result:
Test 2 — Product Type filter:
Status: passed / failed / not executed
Input:
Result count:
Example result:
Test 3 — Nonexistent Product ID:
Status: passed / failed / not executed
Input:
Result count / actual error:
Connection failure or other restriction, if any:
LOCAL SIMULATION, if used:
Class:
Actual output:
Comparison with the two expected SERV rows:
Remote checks still required:
Why this integration approach supports Clean Core:
One thing I had to debug:Finished means: Another developer can understand your code, see what you actually verified, and recognize whether the results came from the remote S/4HANA service.
Helpful references
- Guided Lesson 21: lesson-21-content.md
- Companion: lesson-21-companion.md
- Product API page: https://api.sap.com/api/API_CLFN_PRODUCT_SRV/overview
- SAP Help — Client Proxy: https://help.sap.com/docs/abap-cloud/abap-rap/creating-remote-client-proxy
- SAP Help — SCM wizard: https://help.sap.com/docs/abap-cloud/abap-rap/preparing-access-to-remote-odata-service