Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
Showing results for 
Search instead for 
Did you mean: 
Product and Topic Expert
Product and Topic Expert
Dear friends of fire...

I assume you’re here because you’re new to the SAP Cloud Platform Backend service and also new to the OData and REST service world.
Also new to the swagger and openAPI world
If you’re new to the supercomplexsoftware world…then this blog won’t help you much….

This blog helps you to understand the user interface of the Backend service Cockpit and it helps you to understand some concepts of OData.

You might have started using the Backend service, following some very useful blogs (tutorial, preparation )
You might have had some doubts while starting to use your first API in the browser, in any REST client….. facing problems and getting confused and angry.
Really angry?
As long as you have my tutorials, you don’t need to get angry… simply go ahead and read my explanations, use the Backend service cockpit and the test tool and put away the REST client…. ts ts ts

This blog assumes that you’ve already created APIs using the Backend service and everything is working fine, but you wish some guidance in using and understanding the test tool in the cockpit

The explanation in this blog has the following structure:

0 Details screen header
1 API Access
2.1 Models
2.2 Entities
2.2.1 GET
2.2.2 POST
2.2.3 GET (single)
2.2.4 PATCH
2.2.5 DELETE

Go to your Backend service subscription and open the details of your API
(See here for description)


Details screen header

The header displays some basic information about the chosen API, also the possibility to activate/deactivate and delete the API
That’s all self-explaining.

1 API Access section

The API Access section shows 2 possible endpoints.
For each supported OData version there’s a different endpoint.


There’s no difference with respect on the data that is provided by the backend
There should as well be no big difference in terms of OData features that are supported by the service.
(please refer to the OData spec for a full description on what changed in OData v4.0 compared to previous version:  )

You might need to switch to one or other version depending if the consuming user interface supports only one of the OData versions.
If you don't know which one to use, better use the older protocol version, OData V2, because it is widely adopted.
If you're free to choose, you should take the newer version, OData V4, because it has many improvements (e.g. better performance by using json as default format)


Scroll down to API REFERENCE section.
This is what I call test tool for your API.
It gives an overview on the structure of API and schemata, but also offers buttons which you can press to fire service calls.

As mentioned, the API REFERENCE section contains 2 parts:
Model part and Entities part

2.1 Models part

As mentioned, below API REFERENCE, you have a part where you can see every entity and at the end, you have a part called models.
Let's start with this one, because it might be confusing.
We explain it, afterwards we can forget it.

It means that you can see the schemata that are used when interacting with the API. The structure of possible error responses and the structure of each entity.

The tool is so generic that even navigation properties are resolved. I mean… well, look at the screenshot:

It gives an overview on the names and types of properties.
If your data model is very big, you might easily get lost, I assume, even though you can collapse all sections.
I think we can ignore this “Models” section...

2.2 Entities part

This section lists all entities that are defined in your data model

In your CDS model, you define model elements that are called “entity”.
In the OData world, the corresponding element is called “entity type” in the schema, and “entity set” for the runtime artifacts.

Each entity set has a list of all operations which are supported in general.

GET (to QUERY list)
POST (to CREATE and entity)
GET (to fetch one SINGLE entity)
PATCH (to UPDATE single properties, instead of PUT which is discouraged since OData v4)
DELETE (yes, to delete)

This doesn’t necessarily mean that your API really supports all of them (you can annotate your model elements in order to avoid some of the operations)

2.2.1 GET

Click on GET

A huge section is expanded
Since this is a QUERY operation (means fire a GET request to fetch a list of resources), it is possible to add standard OData parameters (aka "system query options") to the query.
They are listed here in this section.

We cannot discuss the impacts of the parameters, but you can find all details in the OData specification

Below, again, we see the structures of possible responses.
The success response code of a GET operation is the HTTP status code 200 (specified by OData protocol)
The structure with example values which is given by the test tool, does also resolve the navigation property (if available)

This is only meant for information purpose. As long as you don’t “expand” the navigation property (using $expand parameter), there won’t be a nested structure in the response

Now it is time to try it out.

So go ahead and click on “Try it out”
The test tool UI changes and parameters can be edited.
For the moment, leave them empty, don’t click them, just scroll down and click on “Execute”.
The GET request to the OData service is executed and the response can be viewed in the “Responses” section.
The response information is what the server sends back, it contains the HTTP status code, the response body and the response headers

If you receive an error, you can try to just click “Execute” again

If you receive an error like
The property 'null', used in a query expression, is not defined in type 'CustomerEntity'
Then the reason might be that you clicked in a parameter field and some wrong empty value is in the cache
You need to reload the browser – and now you see why I told you not to click….;-)

2.2.2 POST

Click on the GET button to collapse the section and click on POST to expand that section, and click on “Try in out”.
What now?
A POST request is used to create a new resource on the server.
In our words, it creates a new row in a table in the database, which is fully managed by the convenient SAP Cloud Platform Backend service
In OData words, we have to send a json payload (content type) in the request body. The payload has to match the metadata.
For this kind of request, I really appreciate the test tool in the Backend Service cockpit, because I don’t have to manually type the properties which have to be sent in the payload. The tool generates a sample payload for me, based on the metadata.
I only need to fill in the desired (sample) values.

If your entity metadata contains a navigation property, then it is automatically resolved (expanded) in the proposed sample json payload.
It looks like a “Deep Insert” (in OData, you can create an entity and at the same time, child entities, in one request)
However, the deep insert doesn’t work. The entity is created, but hot the child entities.
But that's no problem.
Just an explanation.
As a consequence, you can delete all navigation properties and their expanded properties

When deleting lines in json, make sure to also delete the last comma, otherwise you get an error, malformed json

Example for removing navigation property (luckily in this example the navigation property has an unusual name)

"customerID": 0,
"companyName": "string",
"contactProperty": 0,
"linkToContact": {
"contactID": 0,
"contactName": "string",
"contactPhone": "string"

After removing navigation property:
"customerID": 0,
"companyName": "string",
"contactProperty": 0

Usually, in OData not all properties are mandatory, so you can also delete properties wherever you don’t want to send any value. If you've deleted a mandatory property, you get an error in the service response

After executing the request you get hopefully a positive result.
The success result of a POST in OData is a 201 status and the response body contains the created entity
The created entity is in most cases exactly the same what you've sent in the request payload.
The reason why the data which I’ve sent, is returned in the response:
Typically, some values are computed on the server, for example unique IDs, or dependent values, or timestamps
Furthermore, the “location” header is sent back, which contains the full URL of the created entity

2.2.3 GET

The first operation was a GET request to fetch the full list of entries,
e.g. the collection of products.
This GET request is also called a QUERY
But now we're talking about a GET request which reads a single entry on the server.

An single entity is retrieved by its key property (the key can be composed by multiple key properties)
To get the key, you usually need to previously execute a QUERY

The key is specified in the URL.
For example:

Which is an abbreviation of

In the test tool, while reading a single entity, some parameters are supported.
For now, you only need to enter a value for the key property.
The key field is marked with a red asterisk, you have to enter a value there (no matter if it exists)

2.2.4 PATCH

This UPDATE operation is used to modify an existing entity.
In the past, for updating a resource, the HTTP verb “PUT” was used.
Nowadays, the PUT is still supported by OData, but it is discouraged.
The reason:

PUT: the request body contains all properties, including those which aren’t changed

PATCH: the body only contains those properties which are changed

Which means that patch requests are usually more slim, because usually only few properties are updated. This means less network traffic, as such improving performance
However, PATCH can be also used if all properties are changed.
As such, we don't really need the PUT

More info can be found in the OData spec and here

For executing the PATCH request, you need to specify the key value, in order to identify the entity in the backend, just like you did in the single GET

And you need to specify the properties and values which you want to update.

The success response is 204 and 204 means “no content”, means that the response body is empty

If you want to check the successful modification, you have to execute a subsequent GET request to the same resource

2.2.5 DELETE

Again, this operation is sent to a single entry, so you have to specify the key property value of the entity which you want to delete
This is mandatory

The test tool allows to send an ETag. This might be required by the service

The result of a delete request is “204 no content”. Which is understandable, after deletion there is no content anymore…

In order to verify, you can send the same deletion request again, the result should state “404 not found”

If you get an error response  “428 precondition required”, then the ETag is required.
Workaround: simply enter an asterisk.

If you want to check an OData service metadata document, to find which property is relevant for the ETag (usually a "modified-at"-property), then you won't find any ETag, instead, you have to search for an attribute like this:

ETag? what’s that?
ETag in the OData spec
ETag is usually referred to as: “optimistic concurrency control”, used for “conditional requests”
Imagine an ETag like a timestamp. You read an entity and get the timestamp. If you decide to delete the entity, then you want to delete only the entity with exactly that version. It might have changed in the meantime (concurrency). In that case you don’t want to delete it. This is one example.
Or: you do a request and cache the result and store the eTag. The cache needs to be updated only when the eTag has changed (do request only if condition is matched). This is the second example, should be enough for the moment.


Yes, enough is enough and this is a good moment to end this blog



OData specification:
- The protocol spec
- How URLs have to be composed: URL conventions