Appearance
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
| Part | Example | Purpose |
|---|---|---|
| Scheme | https:// | Uses HTTPS, which encrypts communication |
| Host | jsonplaceholder.typicode.com | Identifies the remote server |
| Path | /posts/1 | Identifies a resource |
| Method | GET, POST, PUT, DELETE | States the requested operation |
| Header | Accept: application/json | Asks for JSON in the response |
| Header | Content-Type: application/json | Describes 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 operation | Typical REST method | Typical target | Request body | Typical status |
|---|---|---|---|---|
| Read | GET | /posts/1 | None | 200 |
| Create | POST | /posts | New resource | 201 |
| Replace or update | PUT | /posts/1 | Complete replacement | 200 or 204 |
| Delete | DELETE | /posts/1 | Usually none | 200 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:
- https://jsonplaceholder.typicode.com/
- https://jsonplaceholder.typicode.com/posts/1
- https://jsonplaceholder.typicode.com/posts/2
- https://jsonplaceholder.typicode.com/guide/
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.
| Test | Expected observation |
|---|---|
| GET post 1 | Returns an existing post |
| POST a new post | Returns a new-looking record, often with ID 101 |
| GET post 101 after POST | May return 404, because it was never stored |
| PUT post 1 | Returns a modified-looking post |
| GET post 1 after PUT | Returns original sample data |
| DELETE post 1 | Returns a successful response, typically empty or {} |
| GET post 1 after DELETE | Returns 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( ).| API | What it does |
|---|---|
CL_HTTP_DESTINATION_PROVIDER=>CREATE_BY_URL | Builds a destination from a direct URL for a simple exercise |
CL_WEB_HTTP_CLIENT_MANAGER=>CREATE_BY_HTTP_DESTINATION | Creates an HTTP client |
GET_HTTP_REQUEST | Obtains the request object |
SET_HEADER_FIELD | Sets one HTTP header |
SET_CONTENT_TYPE | Sets the outgoing body's content type |
SET_TEXT | Adds a text body, such as JSON |
EXECUTE | Makes the request using the selected HTTP method |
GET_STATUS | Returns the HTTP status |
GET_TEXT | Returns the response body as text |
CLOSE | Frees 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/999999is 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
| Symptom | What to check |
|---|---|
HTTP 200 plus a JSON body | GET worked; inspect fields |
HTTP 201 from POST | A create request was accepted; JSONPlaceholder did not store it |
HTTP 200 from DELETE but GET still works | Correct for JSONPlaceholder's simulated delete |
HTTP 404 for /posts/999999 | Expected missing-resource test |
403 or 401 | Endpoint permissions/authentication |
400 | Incorrect path, headers or body; inspect response |
| No status; exception message | URL/destination, TLS, outbound access or other client failure |
| JSON parsing error after 404 | Only deserialize successful, nonempty JSON with the expected structure |
| Browser works, ABAP fails | Browser 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.
| Mechanism | ABAP Cloud pattern | Important distinction |
|---|---|---|
| Bearer | request->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 |
| Basic | request->set_authorization_basic( i_username = ... i_password = ... ) | Uses username/password; Base64 is encoding, not encryption |
| API key | request->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:
- Official base URL and at least one concrete endpoint, including path/query parameters.
- Supported methods: does it allow GET? Are any write methods actually permitted?
- Authentication: none, Bearer, Basic, API key or another scheme?
- Response format and expected fields; is the response an object or an array?
- Example statuses, rate limits, usage terms and whether registration is required.
- 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.
- 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):
- https://github.com/public-apis/public-apis — a directory to help find candidate APIs; check the provider's documentation afterward.
- https://open-meteo.com/en/docs — example of a read-oriented public weather API.
- https://pokeapi.co/docs/v2 — example of a read-oriented public data API.
- https://jsonplaceholder.typicode.com/guide/ — approved simulated-write sandbox for training.
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:
- Browser observation: Visit JSONPlaceholder
/posts/1and its official guide to examine requests and responses. - Offline XCO exercise: Store the sample JSON as an ABAP string and parse it using Section 7; serialize your own JSON with Section 6.
- 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.
- 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
- JSONPlaceholder: https://jsonplaceholder.typicode.com/
- JSONPlaceholder guide (GET/POST/PUT/DELETE behavior): https://jsonplaceholder.typicode.com/guide/
- httpbin Bearer test: https://httpbin.org/bearer
- httpbin API overview: https://httpbin.org/
- API directory: https://github.com/public-apis/public-apis
- Open-Meteo documentation: https://open-meteo.com/en/docs
- PokéAPI documentation: https://pokeapi.co/docs/v2
- SAP Developer, external API and JSON: https://developers.sap.com/tutorials/abap-environment-external-api
- SAP Help, XCO JSON: https://help.sap.com/docs/SAP_S4HANA_CLOUD/6aa39f1ac05441e5a23f484f31e477e7/492ccdb87b224a35a8ed20e53325dfce.html
- SAP Developer, ABAP Console: https://developers.sap.com/tutorials/abap-environment-console-application/