You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: guides/integration/calesi.md
+27-19Lines changed: 27 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -22,9 +22,9 @@ Integrating remote services - from other applications, third-party services, or
22
22
23
23
24
24
25
-
## Introduction & Overview
25
+
## Preliminaries
26
26
27
-
### As If They’re Local
27
+
### Teaser
28
28
29
29
With CAP, Service integration is greatly simplified. Consumption of remote services from other applications, third-party services, or platform services is as easy as calling them _as if they're local_:
30
30
@@ -72,15 +72,24 @@ Remote CAP services can be consumed using the same high-level, uniform APIs as f
72
72
>
73
73
> Note that in the exercise above, the consumer side didn't even have any information about the service provider, except for the URL endpoint and protocols served, which it got from the service binding. In particular no API/service definitions at all – neither in *CDS*, *OData*, nor *OpenAPI*.
74
74
75
-
The remainder of this guide goes beyond such simple scenarios
76
-
and covers all the aspects of CAP-level service integration in detail.
77
75
78
76
79
77
80
78
79
+
### Overview
80
+
81
+
While the above teaser nicely demonstrates the simplicity of CAP-level service integration, CAP can facilitate real-life integration scenarios even more, if we've captured APIs in CDS models. The remainder of this guide walks us through the steps to provide and share such APIs, import them to consuming apps as CDS models and use these in there as if they were local. The graphic below shows the flow of essential steps involved:
82
+
83
+

85
+
86
+
87
+
####
88
+
89
+
81
90
### The XTravels Sample
82
91
83
-
In this guide we'll use the _XTravels_ sample application as our running example. It's a modernized adaptation of the renowned[ABAP Flight reference sample](https://help.sap.com/docs/abap-cloud/abap-rap/abap-flight-reference-scenario), reimplemented using CAP and split into two microservices:
92
+
In this guide we use the _XTravels_ sample application as our running example. It's a modernized adaptation of the [ABAP Flight reference sample](https://help.sap.com/docs/abap-cloud/abap-rap/abap-flight-reference-scenario), reimplemented using CAP and split into two microservices:
84
93
85
94
- The [*@capire/xflights*](https://github.com/capire/xflights) service provides flight-related master data, such as *Flights*, *Airports*, *Airlines*, and *Supplements* (like extra luggage, meals, etc.). It exposes this data via a CAP service API.
86
95
@@ -96,17 +105,13 @@ The resulting entity-relationship model looks like that:
96
105
97
106
From a service integration perspective, this sample mainly shows a data federation scenario, where the application consumes data from different upstream systems (XFlights and S/4HANA) – most frequently in a readonly fashion – to display it together with the application's local data.
98
107
99
-
### Workflow Overview
100
-
101
-
The graphic below shows the flow of essential steps for service integration, which the following sections walk you through in detail:
102
108
103
-

105
109
110
+
#### Getting Started
106
111
107
-
#### Getting Started...
112
+
[`cap/samples`]: #getting-started
108
113
109
-
Let's dive into the details of CAP-level service integration, using the XTravels sample as our running example. Clone both repositories as follows to follow along:
114
+
So, let's dive into the details of CAP-level service integration, using the XTravels sample as our running example. Clone both repositories as follows to follow along:
In case of CAP service providers, as for [*@capire/xflights*](https://github.com/capire/xflights) in our [sample scenario](#the-xtravels-sample), you define [CAP services](../services/index) for all inbound interfaces, which includes (private) interfaces to your application's UIs, as well as public APIs to any other remote consumers.
127
+
In case of CAP service providers, as for [*@capire/xflights*](https://github.com/capire/xflights), you define [CAP services](../services/index) for all inbound interfaces, which includes (private) interfaces to your application's UIs, as well as public APIs to any other remote consumers.
122
128
123
129
124
130
### Defining Service APIs
@@ -447,7 +453,7 @@ npm add @capire/xflights-data
447
453
This makes the exported models with all accompanying artifacts available in the target project's `node_modules` folder. In addition, it adds a respective package dependency to the consuming application's *package.json* like this:
448
454
449
455
::: code-group
450
-
```json [package.json]
456
+
```json [xtravels/package.json]
451
457
{...
452
458
"dependencies": { ...
453
459
"@capire/xflights-data": "0.1.12"
@@ -512,7 +518,7 @@ Instead of importing the same APIs repeatedly in each project, you can import th
512
518
For the _XTravels_ sample, we did so with the [`@capire/s4`](https://github.com/capire/s4) sample package, which we created as follows.
513
519
514
520
515
-
1. We started a new CAP project – get the outcome from Github to follow along:
521
+
1. We started a new CAP project – clone the repository into the [`cap/samples`] folder we created in the beginning and open it in VS Code to follow along:
516
522
517
523
```shell
518
524
git clone https://github.com/capire/s4.git
@@ -773,7 +779,7 @@ There are similar references to `Flights` entity from xflights in other parts of
773
779
774
780
### Mocked Out of the Box
775
781
776
-
With mashed up models, you can run applications in _'airplane mode'_ without upstream services running. CAP mocks imported services automatically _in-process_ with mock data in the same _in-memory_ database as your own data.
782
+
With mashed up modelsin place, we can run applications in _'airplane mode'_ without upstream services running. CAP mocks imported services automatically _in-process_ with mock data in the same _in-memory_ database as our own data.
777
783
778
784
1. Start the xtravels application locally using `cds watch` as usual, and note the output about the integrated services being mocked automatically:
779
785
@@ -801,7 +807,9 @@ With mashed up models, you can run applications in _'airplane mode'_ without ups
801
807
>
802
808
> The mocked-out-of-the-box capabilities of CAP, with remoted services mocked in-process and a shared in-memory database, allows us to greatly speed up development and time to market. For real remote operations there is additional investment required, of course. But the agnostic nature of CAP-level Service Integration also allows you to spawn two working tracks running in parallel: One team to focus on domain and functionality, and another one to work on the integration logic under the hood.
803
809
804
-
We'll learn more about mocking and inner loop development in the [next chapter](./inner-loops).
810
+
Learn more about mocking and inner loop development in the [*Inner Loop Development*](./inner-loops) guide.
Copy file name to clipboardExpand all lines: guides/integration/data-federation.md
+53-42Lines changed: 53 additions & 42 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,47 +1,35 @@
1
1
# CAP-level Data Federation
2
2
3
-
CAP applications can integrate and federate data from multiple external data sources, enabling seamless access and manipulation of distributed data. This guide provides an overview of the core concepts and techniques for implementing data federation in CAP applications, including service-level replication, HANA virtual tables, synonyms, and data products.
3
+
CAP applications can integrate and federate data from multiple external data sources, enabling close access to distributed data. This guide provides an overview of the core concepts and techniques for implementing data federation in CAP applications, and how CAP helps solving this generically, and thus serving data federation out of the box.
4
4
{.abstract}
5
5
6
+
[[toc]]
6
7
7
-
## Introduction & Motivation
8
8
9
-
Displaying external data in lists commonly requires fast access to that data. Relying on live calls to remote services per row is clearly not an option, as that would lead to poor performance, excessive load on server, and a nightmare regarding resilience. Instead, we somehow need to ensure that all required data is available locally, so that it can be accessed fast and reliably by UIs, using good old SQL JOINs.
9
+
## Preliminaries
10
10
11
-
For example, we saw the need for that already in the [CAP-level Service Integration](calesi.md#integration-logic-required) guide, where the `Customer` field in the travel requests list is populated from the remote S/4 Business Partner service, but missing when running the services separately:
11
+
### Prerequisites
12
12
13
-
1. First run these commands **in two separate terminals**:
13
+
You should be familiar with the content in the [_CAP-level Service Integration_](calesi.md) guide, as we build upon that foundation here. In particular, you should have read and understood these sections:
14
14
15
-
```shell :line-numbers=1
16
-
cds mock apis/capire/s4.cds
17
-
```
18
-
```shell :line-numbers=2
19
-
cds mock apis/capire/xflights.cds
20
-
```
15
+
-[*Overview* of *CAP-level Service Integration*](calesi.md#overview)
In addition, you should have read the introduction to [the _XTravels_ sample](calesi.md#the-xtravels-sample) application, which we continue to use as our running example.
21
21
22
-
2. Start the xtravels server as usual **in a third terminal**, and note that it now _connects_ to the other services instead of mocking them:
23
22
24
-
```shell :line-numbers=3
25
-
cds watch
26
-
```
27
-
```zsh
28
-
[cds] - connect to sap.capire.s4.business-partner > odata {
[cds] - connect to sap.capire.flights.data > hcql {
34
-
url: 'http://localhost:54475/hcql/data'
35
-
}
36
-
```
37
23
38
-
2. Open the Fiori UI in the browser again -> data from the S/4 service is missing now, as we have not yet implemented the required custom code for the actual data integration, the same applies to the flight data from _xflights_:
24
+
### Motivation
25
+
26
+
There are many scenarios where data from remote services needs to be in close access locally. For example when we display lists of local data joined with remote data, as we introduce in the [*CAP-level Service Integration*](calesi.md#integration-logic-required) guide:
39
27
40
28

41
29
42
30

43
31
44
-
In addition, when we again look into the log output, we see some bulk requests like shown below, which indicates that the Fiori client is desparately trying to fetch the missing customer data. If we'd scroll the list in the UI this would repeat like crazy.
32
+
When we run that and look into the log output of the xtravels app server, we see some bulk requests as shown below, which indicates that the Fiori client is desparately trying to fetch the missing customer data. If we'd scroll the list in the UI this would repeat like crazy.
45
33
46
34
<spanstyle="font-size:63%">
47
35
@@ -80,37 +68,62 @@ In addition, when we again look into the log output, we see some bulk requests l
80
68
```
81
69
</span>
82
70
71
+
Relying on live calls to remote services per row is clearly not an option. Instead, we'd rather ensure that data required in close access is really available locally, so it can be joined with own data using SQL JOINs. This is what _data federation_ is all about.
72
+
83
73
84
-
## Get The XTravels Sample
85
74
86
-
In the [`@capire/xtravels`](https://github.com/capire/xtravels) app we accomplished that with a simple, yet quite effective data replication solution, which automatically replicates data as documented below.
87
75
88
-
Clone the project from GitHub and open it in VS Code to follow along:
We'll use the same [XTravels sample](calesi.md#the-xtravels-sample) and setup as in the [_CAP-level Service Integration_](calesi.md) guide. If you haven't done so already, clone the required repositories to follow along:
Tag [consumption views](calesi#consumption-views) with the `@federated` annotation, to express your intent to have that data federated, i.e. in close access locally. For example, we did so in out consumption view for S/4 Business Partners:
97
+
Tag [consumption views](calesi#consumption-views) with the `@federated` annotation, to express your intent to have that data federated, i.e. in close access locally. For example, we did so in our consumption view for entities imported from XFlights as well as for the S/4 Business Partners entity:
99
98
100
99
::: code-group
101
-
```cds :line-numbers=4 [apis/capire/s4.cds]
102
-
@federated entity Customers as projection on S4.A_BusinessPartner { ... }
100
+
101
+
```cds :line-numbers [apis/capire/xflights.cds]
102
+
@federated entity Flights as projection on x.Flights { ... }
103
+
@federated entity Supplements as projection on x.Supplements { ... }
103
104
```
105
+
106
+
:::
107
+
::: code-group
108
+
109
+
```cds :line-numbers [apis/capire/s4.cds]
110
+
@federated entity Customers as projection on S4.A_BusinessPartner {
111
+
BusinessPartner as ID,
112
+
PersonFullName as Name,
113
+
LastChangeDate as modifiedAt,
114
+
} where BusinessPartnerCategory == 1; // 1 = Person
> By tagging entities with `@federated` we stay _intentional_ about **_what_** we want to achieve, and avoid any premature assumptions about **_how_** things are actually implemented. => This allows CAP runtimes – or your own _generic_ solutions, as in this case – to choose the best possible implementation strategies for the given environment and use case, which may differ between development, testing, and production environments, or might need to evolve over time.
109
122
110
123
111
-
## Generic Implementation
124
+
## Service-level Replication
112
125
113
-
Here's the complete code, as found in [`srv/data-federation.js`](https://github.com/capire/xtravels/blob/main/srv/data-federation.js):
126
+
Next we implement a generic solution for data federation, which automates the basic hard-coded approach for data federation presented [before](calesi#data-federation). Here's the complete code, as found in [`srv/data-federation.js`](https://github.com/capire/xtravels/blob/main/srv/data-federation.js):
Let's have a closer look at this code, which handles these main tasks:
159
172
160
173
1.**Prepare Persistence** – When the model is `loaded`, before it's deployed to the database, we collect all to be `@federated` entities, check whether their respective services are remote, and if so, turn them into tables for local replicas (line 11).
161
-
162
-
2. **Setup Replication** – Later when all services are `served`, we connect to each remote one (line 20), register a handler for replication (line 21), and schedule it to be invoked every three seconds (line 22).
163
-
174
+
2.**Setup Replication** – Later when all services are `served`, we connect to each remote one (line 20), register a handler for replication (line 21), and schedule it to be invoked repeatedly (line 22).
164
175
3.**Replicate Data** – Finally, the `replicate` handler implements a simple polling-based data federation strategy, based on `modifiedAt` timestamps (lines 28-32), with the actual call to remote happening on line 29.
165
176
166
177
> [!tip] CAP-level Querying -> agnostic to databases & protocols
0 commit comments