Skip to content

Commit ee3b5cb

Browse files
committed
...
1 parent 220be72 commit ee3b5cb

File tree

1 file changed

+52
-3
lines changed

1 file changed

+52
-3
lines changed

guides/integration/calesi.md

Lines changed: 52 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Integrating remote services - from other applications, third-party services, or
1010
>
1111
> 1. Remote services are proxied by CAP services, ... → *everything's a CAP service*
1212
> 2. consumed in protocol-agnostic ways → *... as if they were local*
13-
> 3. mocked out of the box → *inner-loop development*
13+
> 3. mocked out of the box → *fast-track inner-loop development*
1414
> 4. with varying implementations → *evolution w/o disruption*
1515
> 5. extensible through event handlers → *intrinsic extensibility*
1616
>
@@ -801,12 +801,16 @@ With mashed up models, you can run applications in _'airplane mode'_ without ups
801801
802802
![XTravels Fiori list view showing a table of travel requests, with the Customer highlighted in green.](assets/xtravels-list.png)
803803
804+
> [!tip] Fast-track Inner-Loop Development → Spawning Parallel Tracks
805+
>
806+
> 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.
807+
804808
We'll learn more about mocking and inner loop development in the [next chapter](#inner-loop-development).
805809
806810
807811
#### Integration Logic Required
808812
809-
While everything just works nicely when mocked in-process and with a shared in-memory database, let's get a bit more realistic and use `cds mock` to run the services in separate processes.
813+
While everything just works nicely when mocked in-process and with a shared in-memory database, let's move closer to the target setup and use `cds mock` to run the services to be integrated in separate processes.
810814
811815
1. First run these commands **in two separate terminals**:
812816
@@ -881,12 +885,57 @@ The log shows bulk requests – the Fiori client desperately trying to fetch the
881885
We see there are specific implementions required, to actually integrate remote services at runtime. We deep dive into one possible solution for that next.
882886
883887
888+
889+
884890
## Integration Logic
885891
886-
To actually integrate remote services at runtime, custom code is required. In the xtravels sample we implemented that in `srv/travel-service.js`, which is automatically picked up by the CAP runtime as service implementation for the `TravelService` defined in `srv/travel-service.cds`.
892+
This chapter walks you through the typical use cases and solution patterns that you should be aware of when implementing required integration logic. The following sections do that on the example of [CAP Node.js SDK](../../node.js/); the same principles and patterns apply to CAP Java, as documented in the [CAP Java SDK](../../java/) reference documentation.
893+
894+
887895
888896
### Connecting to Remote Services
889897
898+
It all starts with connecting to remote services, which we do like that in the xtravels project:
899+
900+
::: code-group
901+
902+
```js :line-numbers=21 [srv/travel-service.js]
903+
const xflights = await cds.connect.to ('sap.capire.flights.data')
904+
const s4 = await cds.connect.to ('S4BusinessPartnerService')
905+
```
906+
907+
:::
908+
909+
The `cds.connect` functions used here is the common way to address service instances, that is commonly used for and works the same way for both, local as well as remote services:
910+
911+
- for **local** services, it returns the local service providers – i.e., instances of [`cds.ApplicationService`](../../node.js/app-services), or your application-specific subclases thereof.
912+
- for **remote** services, it returns a remote service proxy – i.e., instances of [`cds.RemoteService`](../../node.js/remote-services), generically constructed by the client libs.
913+
- **both** inherit from the [`cds.Service`](../../node.js/core-services) base class, which constitutes the uniform programming interface for consuming CAP services – agnostic to underlying protocols, and agnostic to whether its local or remote at all.
914+
915+
![Diagram illustrating CAP-level service integration showing two scenarios: Local services where Consumer connects to Service via CQL, and Remote services where Consumer connects to Proxy via CQL, Proxy connects to Protocol Adapter via OData, and Protocol Adapter connects to Service via CQL.
916+
](assets/remoting.drawio.svg)
917+
918+
### Uniform, Agnostic APIs
919+
920+
The uniform, agnostic programming interface offered through [`cds.Service`](../../node.js/core-services) is centered around these methods:
921+
922+
- [`srv.send (<request>)`](../../node.js/core-services#srv-send-request) → synchronous communication, for all kinds of services.
923+
- [`srv.emit (<event>)`](../../node.js/core-services#srv-emit-event) → asynchronous communication, via messaging middlewares.
924+
- [`srv.run (<query>)`](../../node.js/core-services#srv-run-query) → execute CRUD queries with services that support that, like CAP services, OData services, or GraphQL services.
925+
926+
Here are some typical usages found in xtravels:
927+
928+
```js
929+
await xflights.send ('POST','BookingCreated', { flight, date, seats })
930+
await xflights.emit ('FlightsUpdated', { flight, date, free_seats })
931+
await xflights.run (SELECT.from`Flights`.where`modifiedAt > ${latest}`)
932+
```
933+
934+
The querying API is the most powerful and closest to the use cases of data-centric business applications.
935+
936+
937+
938+
890939
### Querying Remote Data
891940
892941
### Delegating Queries

0 commit comments

Comments
 (0)