SAP Cloud Platform Integration API Client
npm install @contiva/sap-integration-suite-client

A TypeScript library for SAP Cloud Integration APIs (part of SAP Integration Suite), developed by Contiva GmbH.
Available on npm: sap-integration-suite-client
- Quick Start
- Features
- Installation
- Configuration
- Basic Usage
- API Examples
- Integration Content
- Message Processing Logs
- Security Content
- Message Store
- Log Files
- Advanced Features
- Advanced Clients
- Extension Framework
- Error Handling
- API Documentation
- Testing
- Unit and Integration Tests
- End-to-End Tests
- Troubleshooting
- License
``bashInstall the package
npm install sap-integration-suite-client
`typescript
// Basic usage example
import SapClient from 'sap-integration-suite-client';
import dotenv from 'dotenv';
dotenv.config();// Create client (reads from .env)
const client = new SapClient();
// List integration packages
async function listPackages() {
const packages = await client.integrationContent.getIntegrationPackages();
console.log(
Found ${packages.length} integration packages);
packages.forEach(pkg => console.log(- ${pkg.Name}));
}listPackages().catch(console.error);
`🔍 Features
This client simplifies communication with SAP Integration Suite APIs:
- Complete API Coverage:
- Integration Content - Manage packages, flows, and artifacts
- Message Processing Logs - Monitor message execution
- Message Store - Access persisted messages and payloads
- Security Content - Manage credentials and certificates
- Log Files - Access HTTP and trace logs
- Developer-Friendly:
- TypeScript support with full type definitions
- Promise-based API
- OAuth and CSRF token handling
- Error handling with detailed information
- Advanced Capabilities:
- Bulk operations (retrieving packages with artifacts)
- Error statistics and performance analysis
- Extensible framework for custom clients
📦 Installation
`bash
Using npm
npm install sap-integration-suite-clientUsing yarn
yarn add sap-integration-suite-clientUsing pnpm
pnpm add sap-integration-suite-client
`⚙️ Configuration
You can configure the client through environment variables or direct parameters.
$3
Create a
.env file:`env
Required
SAP_BASE_URL=https://your-tenant.integrationsuitetrial-api.eu10.hana.ondemand.com/api/v1
SAP_OAUTH_CLIENT_ID=your-client-id
SAP_OAUTH_CLIENT_SECRET=your-client-secret
SAP_OAUTH_TOKEN_URL=https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/tokenOptional
SAP_MAX_RETRIES=3
SAP_RETRY_DELAY=1500Redis Caching (Optional)
REDIS_CONNECTION_STRING=your-redis-host:6380,password=xxx,ssl=True,abortConnect=False
REDIS_ENABLED=true
`Then initialize without parameters:
`typescript
import SapClient from 'sap-integration-suite-client';
import dotenv from 'dotenv';
dotenv.config();const client = new SapClient(); // Reads from process.env
`$3
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient({
baseUrl: 'https://your-tenant.integrationsuitetrial-api.eu10.hana.ondemand.com/api/v1',
oauthClientId: 'your-client-id',
oauthClientSecret: 'your-client-secret',
oauthTokenUrl: 'https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token',
// Optional settings
maxRetries: 3, // Default: 0
retryDelay: 1500, // Default: 1000 (ms)
normalizeResponses: true, // Default: true
enableCustomClients: true, // Default: true - Enable advanced client extensions
// Redis caching options
redisConnectionString: 'host:6380,password=xxx,ssl=True',
redisEnabled: true, // Default: false
forceRefreshCache: false, // Default: false - Force background revalidation
noCache: false // Default: false - Disable caching completely
});
`> Note: The
baseUrl should point to the /api/v1 endpoint of your tenant's API service URL.🚀 Redis Caching (Performance Optimization)
This library supports optional Redis-based caching to significantly improve performance and reduce load on SAP systems.
$3
- Stale-While-Revalidate Pattern: Returns cached data immediately while updating in the background
- Hostname-Aware: Multi-tenant support with separate cache per SAP system
- Smart TTL Configuration:
- Standard APIs: 1 hour revalidation, 30 days storage
- Runtime APIs (MessageProcessingLogs, LogFiles): 5 minutes revalidation, 30 days storage
- Selective Caching: Automatically excludes downloads and binary data
- Graceful Degradation: Works seamlessly without Redis
$3
1. Install and configure Redis (Azure Redis Cache, local Redis, etc.)
2. Configure environment variables:
`env
REDIS_CONNECTION_STRING=your-redis.redis.cache.windows.net:6380,password=yourpassword,ssl=True,abortConnect=False
REDIS_ENABLED=true
`3. Use the client normally - caching happens automatically:
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient({
// SAP configuration...
redisEnabled: true,
redisConnectionString: process.env.REDIS_CONNECTION_STRING,
});
// First call: fetches from SAP and caches (slower)
const packages1 = await client.integrationContent.getIntegrationPackages();
// Second call: returns from cache (much faster!)
const packages2 = await client.integrationContent.getIntegrationPackages();
`$3
#### Force Refresh Cache
Force revalidation while still returning cached data (useful after deployments):
`typescript
const client = new SapClient({
// ... other config
redisEnabled: true,
forceRefreshCache: true // Forces background revalidation on every request
});
`#### Disable Caching
Completely bypass cache for specific client instances:
`typescript
const client = new SapClient({
// ... other config
noCache: true // No cache reads or writes
});
`$3
Cached:
- All GET requests to SAP APIs
- Integration packages, flows, and configurations
- Security content metadata
- Message processing logs (with shorter TTL)
Not Cached:
- POST, PUT, DELETE requests
- Binary downloads (
/value, /$value, /download endpoints)
- Custom API extensions (only direct SAP APIs are cached)
- Requests with noCache: true$3
Typical performance improvements with caching enabled:
- Cache Hit: 50-95% faster response times
- Reduced SAP Load: Fewer API calls to SAP systems
- Better Reliability: Stale data served even during SAP outages (within TTL)
$3
Enable debug mode to see cache behavior:
`typescript
process.env.DEBUG = 'true';// Console will show:
// [SapClient] Cache miss: /IntegrationPackages
// [SapClient] Cache hit (fresh): /IntegrationPackages
// [SapClient] Cache needs revalidation (stale): /MessageProcessingLogs
`💡 Basic Usage
After creating a client instance, you can access various API areas through properties:
`typescript
// Access different API clients
client.integrationContent // Integration Content API
client.messageProcessingLogs // Message Processing Logs API
client.messageStore // Message Store API
client.securityContent // Security Content API
client.logFiles // Log Files API// Access advanced clients
client.integrationContentAdvanced // Enhanced Integration Content operations
`📚 API Examples
$3
Manage integration packages, flows, and other artifacts:
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient();
async function managePackages() {
// List packages (with pagination)
const packages = await client.integrationContent.getIntegrationPackages({ top: 5 });
console.log(
Found ${packages.length} packages);
if (packages.length > 0) {
const packageId = packages[0].Id;
// Get integration flows in a package
const flows = await client.integrationContent.getIntegrationFlows(packageId);
console.log(Package ${packages[0].Name} has ${flows.length} integration flows);
// Get a specific flow
if (flows.length > 0) {
const flow = await client.integrationContent.getIntegrationFlowById(flows[0].Id);
console.log(Flow details: ${flow?.Name}, Version: ${flow?.Version});
}
}
}managePackages().catch(console.error);
`$3
Monitor and analyze message execution:
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient();
async function monitorMessages() {
// Get failed messages from the last 24 hours
const yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
const { logs } = await client.messageProcessingLogs.getMessageProcessingLogs({
filter:
Status eq 'FAILED' and LogEnd gt datetime'${yesterday.toISOString()}',
top: 10,
orderby: ['LogEnd desc']
});
console.log(Found ${logs.length} failed messages in the last 24 hours);
for (const log of logs) {
console.log(Message: ${log.MessageGuid}, Flow: ${log.IntegrationFlowName});
// Get error details for a failed message
const errorInfo = await client.messageProcessingLogs.getLogErrorInformation(log.MessageGuid);
if (errorInfo) {
console.log(Error: ${errorInfo.ErrorMessage});
}
}
}monitorMessages().catch(console.error);
`$3
Manage security artifacts like keystores and credentials:
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient();
async function manageKeystore() {
// List keystore entries
const entries = await client.securityContent.getKeystoreEntries('system');
console.log(
Found ${entries.length} entries in the system keystore);
entries.forEach(entry => {
console.log(- ${entry.Alias} (${entry.Type}), Valid until: ${entry.Validity});
});
}manageKeystore().catch(console.error);
`$3
Access persisted messages and their payloads:
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient();
async function accessMessageStore(messageGuid: string) {
// Get store entries for a message
const entries = await client.messageStore.getMessageStoreEntriesForMessage(messageGuid);
console.log(
Found ${entries.length} message store entries);
if (entries.length > 0) {
// Get entry details
console.log(Entry ID: ${entries[0].Id}, Type: ${entries[0].MsgType});
// Get payload (if available)
try {
const payload = await client.messageStore.getMessageStoreEntryPayload(entries[0].Id);
console.log('Payload retrieved successfully');
} catch (error) {
console.error('Failed to retrieve payload');
}
}
}// Replace with a valid message GUID
accessMessageStore('your-message-guid').catch(console.error);
`$3
Access HTTP and trace logs:
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient();
async function accessLogs() {
// List HTTP log files
const logs = await client.logFiles.getLogFiles({
filter: "LogFileType eq 'http'"
});
console.log(
Found ${logs.length} HTTP log files);
if (logs.length > 0) {
const recentLog = logs[0];
console.log(Recent log: ${recentLog.Name}, Size: ${recentLog.Size} bytes);
// Download log content
if (recentLog.Name && recentLog.Application) {
const content = await client.logFiles.downloadLogFile(
recentLog.Name,
recentLog.Application
);
// In Node.js, convert content to string
if (Buffer.isBuffer(content)) {
const textContent = content.toString('utf-8').substring(0, 500);
console.log(Log content preview: ${textContent}...);
}
}
}
}accessLogs().catch(console.error);
`🔧 Advanced Features
$3
The library provides advanced clients with enhanced capabilities and optimized performance:
#### 🚀 Performance Optimizations
The
getPackagesWithArtifacts method includes significant optimizations:
- 50% fewer API calls: MessageMappings & ValueMappings are fetched via global endpoints
- Concurrency control: Prevents rate limiting (HTTP 429) errors
- Configurable parallelization: Adjust concurrency based on your system size#### Basic Usage
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient();
async function advancedOperations() {
// Get packages with all their artifacts in a single operation (sequentially)
const packagesWithArtifacts = await client.integrationContentAdvanced.getPackagesWithArtifacts({
top: 5,
includeEmpty: false // Skip packages without artifacts
});
console.log(
Retrieved ${packagesWithArtifacts.length} packages with their artifacts);
// Example of data available
if (packagesWithArtifacts.length > 0) {
const pkg = packagesWithArtifacts[0];
console.log(Package: ${pkg.package.Name} (${pkg.package.Id}));
console.log(- Integration Flows: ${pkg.artifacts.integrationFlows.length});
console.log(- Value Mappings: ${pkg.artifacts.valueMappings.length});
console.log(- Message Mappings: ${pkg.artifacts.messageMappings.length});
console.log(- Script Collections: ${pkg.artifacts.scriptCollections.length});
}
}advancedOperations().catch(console.error);
`#### ⚡ Parallel Mode with Optimal Concurrency
`typescript
// Fetch packages with optimal parallelization
const packagesWithArtifacts = await client.integrationContentAdvanced.getPackagesWithArtifacts({
parallel: true,
concurrency: 7 // Optimal for most systems (up to 100 packages)
});// Monitor rate limit errors
const rateLimitErrors = client.integrationContentAdvanced.getRateLimitErrorCount();
if (rateLimitErrors > 0) {
console.warn(
⚠️ ${rateLimitErrors} rate limit errors occurred - consider reducing concurrency);
}
`#### 📊 Best Practices for Concurrency
| System Size | Recommended Concurrency | Notes |
|------------|------------------------|-------|
| Small (< 50 packages) |
concurrency: 10 | Safe for most small systems |
| Medium (50-100 packages) | concurrency: 7 | Default - optimal for most |
| Large (100+ packages) | concurrency: 5 | Start low, monitor 429 errors |
| Very Large (200+ packages) | concurrency: 3-5 | Increase carefully |Finding your optimal concurrency:
`bash
Use the included test script
./find-optimal-concurrency.shOr manually test different values
node your-script.js --concurrency 7
`$3
You can extend the library with custom functionality without modifying the
node_modules directory:`typescript
// src/custom/FlowAnalytics.ts
import {
BaseCustomClient,
MessageProcessingLogsClient
} from 'sap-integration-suite-client';// Create your custom client class
export class FlowAnalytics extends BaseCustomClient {
async getFlowPerformance(flowName: string, days = 7) {
const fromDate = new Date();
fromDate.setDate(fromDate.getDate() - days);
const { logs } = await this.client.getMessageProcessingLogs({
filter:
IntegrationFlowName eq '${flowName}' and Status eq 'COMPLETED' and LogEnd gt datetime'${fromDate.toISOString()}',
top: 100
});
// Calculate performance metrics
const durations = logs.map(log => {
const start = new Date(log.LogStart).getTime();
const end = new Date(log.LogEnd).getTime();
return end - start;
});
return {
count: logs.length,
avgDuration: durations.reduce((sum, d) => sum + d, 0) / durations.length || 0,
minDuration: Math.min(...durations) || 0,
maxDuration: Math.max(...durations) || 0
};
}
}// src/custom/FlowAnalyticsFactory.ts
import { CustomClientFactory, MessageProcessingLogsClient } from 'sap-integration-suite-client';
import { FlowAnalytics } from './FlowAnalytics';
export class FlowAnalyticsFactory implements CustomClientFactory {
create(baseClient: MessageProcessingLogsClient): FlowAnalytics {
return new FlowAnalytics(baseClient);
}
}
// src/index.ts - Using your custom client
import SapClient from 'sap-integration-suite-client';
import { FlowAnalyticsFactory } from './custom/FlowAnalyticsFactory';
const client = new SapClient();
// Register your custom factory
client.customClientRegistry.registerFactory('flow-analytics', new FlowAnalyticsFactory());
// Use your custom client
async function analyzeFlowPerformance() {
const analytics = client.customClientRegistry.create('flow-analytics', client.messageProcessingLogs);
const performance = await analytics.getFlowPerformance('MyIntegrationFlow');
console.log('Flow performance:', performance);
}
analyzeFlowPerformance().catch(console.error);
`🎣 Error Handling
The client provides enhanced error objects with additional details:
`typescript
import SapClient from 'sap-integration-suite-client';const client = new SapClient();
async function handleErrors() {
try {
// Try to get a non-existent package
await client.integrationContent.getIntegrationPackageById('non-existent-id');
} catch (error: any) {
console.error('Error occurred:');
console.error(
- Status Code: ${error.statusCode || 'N/A'});
console.error(- Status Text: ${error.statusText || 'N/A'});
console.error(- Message: ${error.message});
// SAP specific error details (if available)
if (error.responseData) {
console.error('- SAP Error:', error.responseData);
}
}
}handleErrors();
`📖 API Documentation
Eine vollständige API-Dokumentation mit allen Klassen, Methoden, Interfaces und Typen ist verfügbar.
$3
`bash
Dokumentation generieren
npm run docsDokumentation im Browser öffnen
npm run docs:serve
`Die Dokumentation wird mit TypeDoc generiert und enthält:
- 📚 Vollständige Methodensignaturen und Beschreibungen
- 🔍 TypeScript-Typen für alle APIs
- 💡 Code-Beispiele und Usage-Patterns
- 🔗 Verlinkte Referenzen zwischen Typen
Weitere Details: Siehe DOCS.md für eine ausführliche Anleitung zur Dokumentation.
🧪 Testing
Das Projekt enthält verschiedene Test-Typen, die für unterschiedliche Zwecke verwendet werden.
$3
Normale Tests (Unit- und Integration-Tests) befinden sich in
tests/units/ und tests/integration/ und werden bei npm run test ausgeführt:`bash
npm run test
`Diese Tests:
- Sind schnell und unabhängig
- Können Mock-Daten verwenden
- Werden automatisch bei jedem Test-Lauf ausgeführt
- Haben keine Abhängigkeiten zu echten SAP-Systemen
$3
End-to-End-Tests arbeiten mit echten SAP-Systemen und echten Daten. Sie sind explizit getrennt von den normalen Tests und werden nur auf explizite Anforderung ausgeführt.
#### Einrichtung
1. Kopieren Sie die Beispiel-Umgebungsvariablen:
`bash
cp .env.e2e.example .env.e2e
`2. Bearbeiten Sie
.env.e2e und tragen Sie Ihre echten SAP-Credentials ein:
`env
SAP_BASE_URL=https://your-tenant.integrationsuitetrial-api.eu10.hana.ondemand.com/api/v1
SAP_OAUTH_CLIENT_ID=your-client-id
SAP_OAUTH_CLIENT_SECRET=your-client-secret
SAP_OAUTH_TOKEN_URL=https://your-tenant.authentication.eu10.hana.ondemand.com/oauth/token
REDIS_CONNECTION_STRING=redis://localhost:6379
REDIS_ENABLED=true
`#### Ausführung
`bash
Alle E2E-Tests ausführen
npm run test:e2eWatch-Mode für Entwicklung
npm run test:e2e:watchVerbose-Mode für detailliertes Logging
npm run test:e2e:verbose
`#### Unterschiede zu normalen Tests
| Feature | Normale Tests | E2E-Tests |
|---------|--------------|-----------|
| Ausführung |
npm run test | npm run test:e2e |
| Daten | Mock-Daten möglich | Echte SAP-Daten |
| Geschwindigkeit | Schnell | Langsamer (echte API-Calls) |
| Abhängigkeiten | Keine externen Systeme | Benötigt SAP-System |
| Timeout | 30 Sekunden | 60 Sekunden |Wichtig: E2E-Tests werden nicht bei
npm run test ausgeführt und sind standardmäßig in CI/CD-Pipelines deaktiviert.Weitere Informationen finden Sie in der E2E-Test-Dokumentation.
❓ Troubleshooting
Common issues and solutions:
$3
- OAuth Errors: Verify your Client ID, Client Secret, and Token URL
- Permission Errors: Ensure your OAuth client has the necessary roles assigned (IntegrationDeveloper, etc.)
$3
- 404 Not Found: Check that your
baseUrl is correct and includes /api/v1`- Neo vs. Cloud Foundry: Some APIs are environment-specific (Neo-only or CF-only)
- Tenant Configuration: Verify your tenant has the APIs you need enabled
MIT © Contiva GmbH
---
Developed by Contiva GmbH - https://contiva.com