5. Prebuilt Integration Packages - SAP-samples/teched2022-AD265 GitHub Wiki

In this exercise, you will see how an integration package can be embedded into an application. The goal is to make reusable code available for others, to let them benefit from prefabricated integrations.

Build

First, let's create a new NPM package next to the application folder:

cd `git rev-parse --show-toplevel`  # go to project root
mkdir s4-bupa-integration
cd s4-bupa-integration
npm init -y

Then copy the contents of the srv/external folder to a bupa folder here:

cp -r ../incidents/srv/external/ bupa

Use npm pack to preview the content of the package:

npm pack

which outputs:

npm notice 📦  [email protected]
npm notice === Tarball Contents ===
npm notice 319.6kB bupa/API_BUSINESS_PARTNER.csn
npm notice 363.7kB bupa/API_BUSINESS_PARTNER.edmx
npm notice 311B    bupa/API_BUSINESS_PARTNER.js
npm notice 107B    bupa/data/API_BUSINESS_PARTNER-A_BusinessPartner.csv
npm notice 625B    bupa/index.cds
npm notice 233B    package.json
npm notice === Tarball Details ===
npm notice name:          s4-bupa-integration
npm notice version:       1.0.0
npm notice filename:      s4-bupa-integration-1.0.0.tgz
...
s4-bupa-integration-1.0.0.tgz

You see that NPM has nicely packaged all your content.

You can influence what gets packaged with the files field in package.json or an .npmignore file.

Publish

There are different options to make the package available for usage in applications:

  • Via npmjs.com: this is the preferred way for free usage by anyone. It requires an NPM account. See the NPM docs for more.
  • Via GitHub: just push the package sources to a repository on github.com, and you can refer to the package with a git+https://github.com/... URL during npm install. You can even refer to a specific branch of the repository.
  • Via a tgz file like the one you built above. This doesn't need to be stored locally, but can also be served by a remote host.
  • Via a local folder

See the NPM docs for more details.

For this tutorial, we use the local folder approach, as it's the most convenient for fast development roundtrips. Also, it doesn't require you to use a GitHub or an NPM account.

Note though, that for basic cloud deployments local folders won't work. There, you need to have publicly accessible hosts for your packages, like npmjs.com or github.com, so that NPM can download the packages during deployment. This restriction can in turn be mitigated by vendoring, i.e. including your packages in deployment archives (like SAP's multi-target archive format MTA). This is beyond the scope of this tutorial, though.

Install

Go back to the incidents application and install the folder like any other NPM dependency:

cd ../incidents
npm add ../s4-bupa-integration

The package was added as a file: dependency in package.json.

Let's see what got installed by expanding the folder node_modules/s4-bupa-integration (in the file explorer or in the terminal):

node_modules/s4-bupa-integration
├── bupa
│   ├── API_BUSINESS_PARTNER.csn
│   ├── API_BUSINESS_PARTNER.edmx
│   ├── API_BUSINESS_PARTNER.js
│   ├── data
│   │   └── API_BUSINESS_PARTNER-A_BusinessPartner.csv
│   └── index.cds
└── package.json

As expected, all files are available. Note though that node_modules/s4-bupa-integration is a symlink to the actual package directory ../s4-bupa-integration. This means that any change there will be immediately visible in the application, which is great for development roundtrips!

Use

Replace the using ... from './external' line in srv/mashup.cds with

using { s4 } from 's4-bupa-integration/bupa';

Note the path difference in the from 's4-bupa-integration/bupa' clause. For NPM packages – and this is what we have here – it starts with the package name right away, i.e. without a leading ./ Also, the /bupa path is actually /bupa/index.cds, but index.cds can always be omitted.

Now delete folder srv/external.

Start the application with cds watch again, and you can see in the log that the model files from the ../s4-bupa-integration/ package are used, as well as the mock implementation ../s4-bupa-integration/bupa/API_BUSINESS_PARTNER.js:

[cds] - loaded model from 7 file(s):

  db/schema.cds
  ...
  ../s4-bupa-integration/bupa/index.cds
  ../s4-bupa-integration/bupa/API_BUSINESS_PARTNER.csn
...
[cds] - mocking API_BUSINESS_PARTNER { path: '/api-business-partner', impl: '../s4-bupa-integration/bupa/API_BUSINESS_PARTNER.js' }

The application works as before!

Summary

You've now learned how to add an integration package. You've also seen that quite some application code became obsolete and could be removed:

  • The imported edmx file and the resulting csn file
  • The js mock implementation and sample data

And that additional features can be added in such packages, like

  • Event definitions
  • Event emitters for local testing
  • CDS projections for model parts that are often used, like the Customers definition.
  • Additional annotations, like for SAP Fiori Elements

The following picture shows how the integration/reuse package and the application project work together on a technical level.

Let's do a general wrap-up of what you have seen.