SAP CAP: Working with eTags
In this SAP Note, I’d like to describe what an eTag is and how this mechanism can be leveraged in CAP projects.
What is CAP?
The Cloud Application Programming Model (CAP) is a framework of languages, libraries, and tools for building enterprise-grade cloud applications. It guides developers along a golden path of proven best practices, which are served out of the box by generic providers cloud-natively, thereby relieving application developers from tedious recurring tasks.
What is an eTag?
eTag stands for Entity Tag and is used in OData services to track the version of an entity entry. In SAP CAP, you mark a property (usually a timestamp or version field) with the @odata.etag
annotation, enabling version control at the API level.
Technically, eTags are part of the HTTP specification and are used to implement optimistic concurrency control. More details can be found in the HTTP spec:

Why would I need to use an eTag in my project?
Using eTags helps prevent data inconsistencies when multiple users or systems interact with the same entity.
Let’s say your application manages news posts. As a chief editor, you notice a grammar mistake and decide to fix it. You open the post, make your correction, and hit Save. But—suddenly—you get the error:
The post/article/order... has been updated. Please refresh the page
You refresh the page and notice that the changes have already been made—someone else updated the post before you.
This is where eTags come into play: they detect whether the entry was modified since you last fetched it, thus avoiding unintentional overwrites.
Let’s now look under the hood and implement a basic CAP scenario to demonstrate eTag behavior.
Scenario
In this note, I’ll walk through a simple example: creating a CAP service that stores news posts and uses eTags to detect concurrent updates.
Initial setup
Refer to this guide to set up a basic CAP project:
Create a new folder and initialize the CAP project
Create a new folder for your project by running the following command (in the example below, proj2
is the name of the folder where all the project files will reside).
cds init proj2

Define a Domain Model for your project
In our example, we’ll model a simple news feed. Create a new file named schema.cds
inside the db
folder with the following content:

namespace sap.localhost.newsintranet;
entity News {
key ID : Integer;
news_title : localized String(200);
news_body : localized String;
@odata.etag
editedAt : Timestamp
}
Define a Service for the Model
Create a service.cds
file inside the srv
folder:
using {sap.localhost.newsintranet as news} from '../db/schema';
service NewsService {
entity News as projection on news.News;
}

Run the service
To run your service locally:
cds watch

Then open http://localhost:4004
in your browser. You’ll see the CAP admin UI. Click the News Service
endpoint to inspect your entity:


Add Mock Data
Let’s add data to your service by running the command below in the terminal.
cds add data

This will generate a data
folder under db
and a .csv
file for your entity. Populate the CSV with some test records.


Once saved and deployed, refresh your browser—your test entries should now be visible.

You can also access individual entries:
GET http://localhost:4004/odata/v4/news/News(1)

Check the terminal for logs—it often provides helpful insights or warnings.


What About eTags?
Let’s dive into the main topic: how to use the eTag value. Open Postman, send a GET
request to your service, e.g.:

In the response body, you’ll see the @odata.etag
field. In the response headers, locate the ETag
value—it represents the current version of the entity.

How to Use the eTag Value (1)
Now, let’s simulate an update. Copy the ETag
value from the GET response

Add the If-Match
header with the copied eTag value.

Add your update payload:

Click Send:

You should receive a 200 OK
response. This means the entity was updated because the eTag matched the server's current version.
If-Match
header, CAP will automatically determine whether the update should proceed based on whether the record has been modified. You don’t need to implement custom logic for this check.How to Use the eTag Value (2)
Now let’s test a conflict. Manually change the editedAt
value in your CSV file for a given record (e.g., from 2025-01-02T23:56:00Z
to 2025-01-02T23:57:00Z
)

Use Postman to send a PATCH
request with the old eTag in the If-Match
header:

You’ll get a 412 Precondition Failed response:

This response tells you that the record has changed, and your update was blocked to avoid overwriting new data. To proceed, you’d need to GET
the latest eTag again and retry your update.
This was a long one—but I hope it clarified how eTags work in SAP CAP and how you can use them to protect your data from concurrency issues.
I plan to continue exploring CAP topics and sharing tips that might be helpful for real-world projects. Cheers!