Skip to content

HTTP Workshop Companion — REST API Reference ​

Use this companion when a term is unfamiliar, you need to review an ABAP HTTP method, or a response is unexpected. It supports the HTTP Workshop and is a reference you can return to while working independently.

1. The single idea behind an API ​

An API provides a documented way for two applications to exchange information. Your ABAP program does not need access to the other application's database. It asks the other application to perform an operation.

A REST API is an API that organizes its operations around resources identified by URLs and commonly uses HTTP methods. For example, JSONPlaceholder exposes a collection of fake posts at /posts. Your ABAP application can request an individual post at /posts/1.

The same URL can support several operations. The HTTP method tells the API which operation you intend.

text
HTTP client                       HTTP server
     |                                  |
     |  PUT /posts/1                    |
     |  Content-Type: application/json  |
     |  {"id":1,...}                    |
     |--------------------------------->|
     |                                  |
     |  HTTP 200 + JSON                 |
     |<---------------------------------|

2. Anatomy of an HTTP request ​

PartExamplePurpose
Schemehttps://Uses HTTPS, which encrypts communication
Hostjsonplaceholder.typicode.comIdentifies the remote server
Path/posts/1Identifies a resource
MethodGET, POST, PUT, DELETEStates the requested operation
HeaderAccept: application/jsonAsks for JSON in the response
HeaderContent-Type: application/jsonDescribes the format of the request body
Body{"title":"...","body":"...","userId":1}Data supplied to POST or PUT

Accept and Content-Type are different. Accept describes what response format the client would like; Content-Type describes the format of the data the client is sending.

Anatomy of an HTTP response ​

text
HTTP/1.1 201 Created
Content-Type: application/json

{"title":"New post","body":"Example","userId":1,"id":101}

The status code is separate from the body. A success response can legitimately have an empty body, especially after DELETE. Do not attempt JSON deserialization when the body is empty.

3. CRUD and HTTP methods ​

ABAP business operationTypical REST methodTypical targetRequest bodyTypical status
ReadGET/posts/1None200
CreatePOST/postsNew resource201
Replace or updatePUT/posts/1Complete replacement200 or 204
DeleteDELETE/posts/1Usually none200 or 204

PUT versus PATCH: PUT normally sends the desired full resource representation; PATCH usually sends only changes. The HTTP Workshop focuses on PUT, not PATCH.

Idempotency: GET, PUT and DELETE are typically idempotent in their intended effect (repeating the same request aims at the same final server state). POST is not generally idempotent. Idempotence does not mean every repeated request must have an identical status or body; deleting an already-deleted resource can produce 404.

Safety of GET: GET should only retrieve data, not deliberately modify server state. Avoid implementing business-changing actions as GET requests.

4. The test service is deliberately fake ​

Official URLs:

JSONPlaceholder contains sample posts. It also accepts POST, PUT and DELETE requests but does not persist them. This is documented behavior, not a failure of the ABAP client.

TestExpected observation
GET post 1Returns an existing post
POST a new postReturns a new-looking record, often with ID 101
GET post 101 after POSTMay return 404, because it was never stored
PUT post 1Returns a modified-looking post
GET post 1 after PUTReturns original sample data
DELETE post 1Returns a successful response, typically empty or {}
GET post 1 after DELETEReturns original sample data

Do not equate HTTP 201 or 200 with durable storage. For real business applications, verify persistence using a supported follow-up read or authoritative system behavior.

5. ABAP Cloud HTTP client: what each object does ​

abap
DATA(destination) = cl_http_destination_provider=>create_by_url(
  i_url = 'https://jsonplaceholder.typicode.com/posts/1' ).

DATA(client) = cl_web_http_client_manager=>create_by_http_destination(
  i_destination = destination ).

DATA(request) = client->get_http_request( ).
request->set_header_field(
  i_name = 'Accept' i_value = 'application/json' ).

DATA(response) = client->execute( i_method = if_web_http_client=>get ).
DATA(status) = response->get_status( ).
DATA(json) = response->get_text( ).
client->close( ).
APIWhat it does
CL_HTTP_DESTINATION_PROVIDER=>CREATE_BY_URLBuilds a destination from a direct URL for a simple exercise
CL_WEB_HTTP_CLIENT_MANAGER=>CREATE_BY_HTTP_DESTINATIONCreates an HTTP client
GET_HTTP_REQUESTObtains the request object
SET_HEADER_FIELDSets one HTTP header
SET_CONTENT_TYPESets the outgoing body's content type
SET_TEXTAdds a text body, such as JSON
EXECUTEMakes the request using the selected HTTP method
GET_STATUSReturns the HTTP status
GET_TEXTReturns the response body as text
CLOSEFrees the client's resources

For production integrations, use a configured outbound destination or communication arrangement appropriate to your landscape, instead of hard-coding endpoints and credentials. The guided workshop uses a direct public URL only to teach HTTP mechanics.

Why IF_WEB_HTTP_CLIENT=>GET is not a URL ​

GET is an ABAP constant representing an HTTP method. It tells the client how to use the URL you supplied. Changing the URL without changing the method is not the same operation as changing GET to POST or DELETE.

6. Safely constructing request bodies ​

For the guided class, we used a short JSON literal:

abap
DATA(json_text) = '{"title":"Training","body":"Hello from ABAP","userId":1}'.
request->set_content_type( 'application/json; charset=UTF-8' ).
request->set_text( json_text ).

This is easy to read, but concatenating arbitrary user input into JSON by hand is dangerous: quotes, backslashes and special characters require escaping. Serialize an ABAP structure instead for real applications.

Example using released XCO JSON:

abap
TYPES: BEGIN OF ty_new_post,
         title   TYPE string,
         body    TYPE string,
         user_id TYPE i,
       END OF ty_new_post.

DATA(new_post) = VALUE ty_new_post(
  title   = 'Training'
  body    = 'Hello from ABAP'
  user_id = 1 ).

DATA(json_text) = xco_cp_json=>data->from_abap( new_post
  )->apply( VALUE #(
    ( xco_cp_json=>transformation->underscore_to_camel_case )
  ) )->to_string( ).

"Produces JSON with userId instead of user_id.

The transformation is important because the API field is userId whereas idiomatic ABAP uses user_id.

7. Converting JSON returned by the API ​

When the service returns a single post as JSON:

json
{"userId":1,"id":1,"title":"Example","body":"Example text"}

You can parse it into a typed structure:

abap
TYPES: BEGIN OF ty_post,
         user_id TYPE i,
         id      TYPE i,
         title   TYPE string,
         body    TYPE string,
       END OF ty_post.

DATA(post) = VALUE ty_post( ).

xco_cp_json=>data->from_string( json_text
  )->apply( VALUE #(
    ( xco_cp_json=>transformation->pascal_case_to_underscore )
  ) )->write_to( REF #( post ) ).

Important: This code expects one JSON object. A /posts GET returns a JSON array ([ ... ]) and requires a compatible ABAP table structure, not a single post structure. A HTTP error may return empty text or an error document rather than the expected post object; check the status before parsing.

8. HTTP failures versus ABAP exceptions ​

Two different kinds of problem must be handled.

A. The API responds with a failure status ​

Examples: 404, 400, 500.

  • The client contacted an HTTP server and received a status.
  • Check the code, response body and request path.
  • A 404 for /posts/999999 is a deliberate negative test.

B. ABAP raises a client/destination exception ​

Examples: DNS/network blocking, TLS issue, destination resolution failure, connection timeout.

  • You may not have received an HTTP response at all.
  • Read the exception text; record it, and test connectivity independently.
  • Your ABAP Trial's outbound policies may differ from a browser's connection.

The lessons' CATCH cx_root block is intentionally simple for initial diagnosis. In production code, prefer more specific exception handling (CX_HTTP_DEST_PROVIDER_ERROR, CX_WEB_HTTP_CLIENT_ERROR) and intentional error propagation.

Quick troubleshooting table ​

SymptomWhat to check
HTTP 200 plus a JSON bodyGET worked; inspect fields
HTTP 201 from POSTA create request was accepted; JSONPlaceholder did not store it
HTTP 200 from DELETE but GET still worksCorrect for JSONPlaceholder's simulated delete
HTTP 404 for /posts/999999Expected missing-resource test
403 or 401Endpoint permissions/authentication
400Incorrect path, headers or body; inspect response
No status; exception messageURL/destination, TLS, outbound access or other client failure
JSON parsing error after 404Only deserialize successful, nonempty JSON with the expected structure
Browser works, ABAP failsBrowser and ABAP backend have different outbound networks

9. Authentication headers, credentials and safe testing ​

An API may be public (no credentials) or protected. A protected API's documentation tells you whether it expects a Bearer token, Basic authentication, an API key, or another mechanism.

MechanismABAP Cloud patternImportant distinction
Bearerrequest->set_header_field( i_name = 'Authorization' i_value = 'Bearer <demo-token>' )A header format; a real bearer token must be obtained securely from the issuer
Basicrequest->set_authorization_basic( i_username = ... i_password = ... )Uses username/password; Base64 is encoding, not encryption
API keyrequest->set_header_field( i_name = 'X-API-Key' i_value = ... )Provider-specific: header names and value formats differ

For teaching: https://httpbin.org/bearer normally gives 401 without Authorization: Bearer ... and 200 with a demo Bearer value. It does not validate a real OAuth token. Use only a fictional demonstration value because some echo services show supplied headers or tokens in their responses. Never paste real credentials into public websites, test services, ABAP source, console output, screenshots or submissions.

For production: Use HTTPS, the provider's permitted authentication flow, and approved secure destination/communication arrangements. CREATE_BY_URL is appropriate for public or test services, not a reason to hard-code real credentials.

Status interpretation: A returned 401/403 proves the remote server responded; it does not necessarily mean the network connection failed. An ABAP exception can happen before a response is available.

Discovery checklist for an unfamiliar API ​

Before coding, confirm all of the following in the provider's own documentation:

  1. Official base URL and at least one concrete endpoint, including path/query parameters.
  2. Supported methods: does it allow GET? Are any write methods actually permitted?
  3. Authentication: none, Bearer, Basic, API key or another scheme?
  4. Response format and expected fields; is the response an object or an array?
  5. Example statuses, rate limits, usage terms and whether registration is required.
  6. Whether test writes are explicitly safe and permitted. Never try POST/PUT/DELETE on a production account or arbitrary API just to see what happens.
  7. Whether the browser and the ABAP Trial backend can reach it; these are separate checks.

Discovery starting points (not required or guaranteed to be accessible from every Trial tenant):

If the selected API is read-only, that is a valid discovery choice. Demonstrate GET against it and use a documented sandbox such as JSONPlaceholder for POST/PUT/DELETE. You should not make real changes merely to satisfy a school assignment.

10. What if JSONPlaceholder is blocked in BTP Trial? ​

A public HTTP destination is not guaranteed to work in every Trial tenant. The SAP Developer tutorial about consuming an external API describes setups requiring licensed communication-management features and explicitly states that its full tutorial is not compatible with Trial. That restriction does not prove direct CREATE_BY_URL is always blocked; it means Trial support for a particular outbound configuration must be tested rather than assumed.

Use these alternatives without making false claims:

  1. Browser observation: Visit JSONPlaceholder /posts/1 and its official guide to examine requests and responses.
  2. Offline XCO exercise: Store the sample JSON as an ABAP string and parse it using Section 7; serialize your own JSON with Section 6.
  3. Verified Trial connection: If a shared S/4HANA communication arrangement is working in your environment, use it only for a permitted read-only GET exercise. Do not send POST/PUT/DELETE requests to the shared S/4HANA Product API.
  4. Record the difference between code that activates, a successful real HTTP request, and a simulated/offline result.

11. Knowledge check — explanations ​

Why does a URL alone not determine an operation? Because the HTTP method also matters; GET and DELETE on the same path express different intentions.

Why do POST and PUT need a JSON request body here? The server needs the fields for the created or replacement record.

Why doesn't DELETE return a JSON post? Its job is to request removal; a successful delete often has no meaningful response body.

Why is a 404 different from an exception? A 404 is a completed HTTP exchange with a not-found response; a connection exception may happen before any response arrives.

Why are the changes not visible afterward? JSONPlaceholder is a fake API that simulates modification responses without writing data to storage.

What is the bridge to Lesson 21? You already know how to send HTTP and inspect JSON. Lesson 21 introduces OData metadata (EDMX) and a Service Consumption Model so ABAP can consume the SAP OData service using generated types and an OData client proxy.

12. References ​