Skip to main content

Integration Guide

SoftyFlow provides comprehensive integration capabilities that allow you to connect with external systems and services. This guide covers the three main integration methods available in SoftyFlow.

1. EDS API Integration (Outgoing Integrations)

Overview

External Data Sources (EDS) API integration allows SoftyFlow to consume external REST APIs as data sources. This enables seamless integration with third-party services and systems.

API EDS Configuration

Configure API EDS to connect with external REST APIs:

{
baseURL: "https://api.example.com", // Base API URL (optional)
timeout: 30000, // Request timeout in milliseconds
connectionUrl: "/health", // Test connection endpoint
headers: { // Global headers
"Content-Type": "application/json",
"Accept": "application/json"
},
runScript: ` // Pre-execution script
// Fetch authentication token
const response = await SF.utils.axios.get('/auth/token', {
headers: { 'X-API-Key': 'your-api-key' }
});
return {
authToken: response.data.token
};
`,
endpoints: [ // API endpoint definitions
{
type: "retrieve", // Operation type
method: "GET", // HTTP method
value: "/{{SF_table}}/{{SF_source._id}}", // URL pattern
headers: { // Endpoint-specific headers
"Authorization": "Bearer {{authToken}}"
},
params: { // Query parameters
"include": ["relations"],
"fields": "{{SF_source.fields}}"
},
response: ` // Response transformation
return SF_result.data;
`
}
]
}

Available API Endpoint Types

  • retrieve: Get single record by ID
  • list: Get multiple records with pagination
  • count: Count records matching criteria
  • insert: Create new record
  • insertMany: Create multiple records
  • update: Update existing record
  • delete: Delete record
  • execute: Custom operations

Context Variables Available

  • SF_source: Data source and query parameters
  • SF_table: Table/resource name
  • SF_postData: Data for POST/PUT operations
  • SF_limit: Maximum records to retrieve
  • SF_sortby: Sort field name
  • SF_page: Current page number
  • SF_direction: Sort direction (1 or -1)

Complete API EDS Example

{
baseURL: "https://jsonplaceholder.typicode.com",
timeout: 30000,
connectionUrl: "/posts/1",
headers: {
"Content-Type": "application/json"
},
runScript: `return { timestamp: Date.now() }`,
endpoints: [
{
type: "retrieve",
method: "GET",
value: "/{{SF_table}}/{{SF_source._id}}",
headers: "{}",
params: "{}",
response: "return SF_result"
},
{
type: "list",
method: "GET",
value: "/{{SF_table}}",
headers: "{}",
params: `{
_page: SF_page,
_limit: SF_limit,
_sort: SF_sortby,
_order: SF_direction === 1 ? 'asc' : 'desc'
}`,
response: "return SF_result"
},
{
type: "insert",
method: "POST",
value: "/{{SF_table}}",
headers: "{}",
params: "SF_postData",
response: "return SF_result"
}
]
}

Using API EDS in Actions

{
action: "findMany (EDS)",
parameters: {
dumpVar: "apiData",
clientDatabase: { _id: "my_api_eds", name: "External API" },
table: "users",
find: {
status: "active",
department: "{{selectedDepartment}}"
}
}
}

Using API EDS in Widgets

{
name: "External Data Table",
model: "externalData",
options: {
remote: "EDS",
clientDatabase: {
_id: "api_eds",
name: "External API"
},
edsSource: "users",
query: {
status: "active",
department: "{{selectedDepartment}}"
},
sortBy: "created_at",
direction: -1,
limit: 25
}
}

2. Scripts via Axios (Process Modeler SDK)

Overview

The Process Modeler SDK provides access to axios for making HTTP requests within process scripts, allowing for flexible API integrations during workflow execution.

Basic Axios Usage

// GET request
let response = await SF.utils.axios.get('/data/json/123')
.then(function (response) {
// handle success
console.log(response);
return response.data;
}).catch(function (error) {
// handle error
console.log(error);
});

POST Requests

// POST request with data
let body = {
"email": "client1@gmail.com",
"name": "John Doe"
}

let result = await SF.utils.axios.post('https://api.example.com/users', body, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token
}
});

PUT Requests

// PUT request for updates
let updateData = {
"status": "active",
"lastLogin": new Date()
}

let updateResult = await SF.utils.axios.put('https://api.example.com/users/123', updateData);

DELETE Requests

// DELETE request
let deleteResult = await SF.utils.axios.delete('https://api.example.com/users/123');

Authentication Examples

Bearer Token Authentication

let config = {
headers: {
'Authorization': 'Bearer ' + authToken,
'Content-Type': 'application/json'
}
};

let result = await SF.utils.axios.get('https://api.example.com/protected', config);

API Key Authentication

let apiConfig = {
headers: {
'X-API-Key': 'your-api-key',
'Content-Type': 'application/json'
}
};

let apiResult = await SF.utils.axios.post('https://api.example.com/data', data, apiConfig);

Complex Integration Example

// Multi-step API integration
try {
// Step 1: Authenticate
let authResponse = await SF.utils.axios.post('https://api.example.com/auth', {
username: 'user',
password: 'pass'
});

let token = authResponse.data.token;

// Step 2: Fetch data with authentication
let dataResponse = await SF.utils.axios.get('https://api.example.com/data', {
headers: {
'Authorization': 'Bearer ' + token
}
});

// Step 3: Process and store data
let processedData = dataResponse.data.map(item => ({
id: item.id,
name: item.name,
processed_at: new Date()
}));

// Step 4: Save to SoftyFlow collection
await SF.collection.insertMany("external_data", processedData);

return { success: true, count: processedData.length };

} catch (error) {
console.error('Integration failed:', error);
return { success: false, error: error.message };
}

3. Incoming APIs (SoftyFlow APIs)

Overview

SoftyFlow allows you to create APIs that external systems can call, enabling inbound integrations and webhooks.

API Configuration Variables

When creating SoftyFlow APIs, these variables are available:

  • SF_body: Contains API body data
  • SF_headers: Contains API header data
  • SF_query: Contains API query data
  • SF_mode: The execution mode of the API (test, uat, prod)
  • SF_initiator: Contains the user who launched the API

Example API Implementation

// Process incoming data
let requestData = SF_body;
let headers = SF_headers;
let queryParams = SF_query;

// Validate incoming data
if (!requestData.email) {
return {
error: "Email is required",
status: 400
};
}

// Process the request
let result = await SF.collection.insertOne("customers", {
email: requestData.email,
name: requestData.name,
created_at: new Date(),
created_by: SF_initiator._id
});

// Return response
return {
success: true,
customer_id: result.insertedId,
message: "Customer created successfully"
};

Advanced API Example

// Advanced customer management API
let { action, customerId, customerData } = SF_body;
let authHeader = SF_headers.authorization;

// Authentication check
if (!authHeader || !authHeader.startsWith('Bearer ')) {
return {
error: "Unauthorized",
status: 401
};
}

try {
switch (action) {
case 'create':
// Validate required fields
if (!customerData.email || !customerData.name) {
return {
error: "Email and name are required",
status: 400
};
}

// Check if customer exists
let existingCustomer = await SF.collection.findOne("customers", {
email: customerData.email
});

if (existingCustomer) {
return {
error: "Customer already exists",
status: 409
};
}

// Create customer
let newCustomer = await SF.collection.insertOne("customers", {
...customerData,
created_at: new Date(),
created_by: SF_initiator._id
});

return {
success: true,
customer: newCustomer,
message: "Customer created successfully"
};

case 'update':
if (!customerId) {
return {
error: "Customer ID is required",
status: 400
};
}

let updatedCustomer = await SF.collection.updateOne("customers",
{ _id: customerId },
{
...customerData,
updated_at: new Date(),
updated_by: SF_initiator._id
}
);

return {
success: true,
customer: updatedCustomer,
message: "Customer updated successfully"
};

case 'delete':
if (!customerId) {
return {
error: "Customer ID is required",
status: 400
};
}

await SF.collection.deleteOne("customers", { _id: customerId });

return {
success: true,
message: "Customer deleted successfully"
};

case 'get':
if (customerId) {
let customer = await SF.collection.findOne("customers", { _id: customerId });
return {
success: true,
customer: customer
};
} else {
let customers = await SF.collection.find("customers", {});
return {
success: true,
customers: customers
};
}

default:
return {
error: "Invalid action",
status: 400
};
}
} catch (error) {
return {
error: "Internal server error",
message: error.message,
status: 500
};
}

Calling SoftyFlow APIs

1. Using InvokeApi Action

{
action: "InvokeApi",
parameters: {
api: { _id: "api_id", name: "Customer API" },
dumpVar: "apiResponse",
body: {
action: "create",
customerData: {
email: "customer@example.com",
name: "John Smith"
}
}
}
}

2. Using External HTTP Calls

let body = {
"action": "create",
"customerData": {
"email": "client1@gmail.com",
"name": "John Doe"
}
}

let apiUrl = "https://softydev.softyflow.io/api/v1/api/6491696d1ef51ed2f7044b79?SF_mode=prod";
// SF_mode values: test, uat, prod

let result = await axios.post(apiUrl, body, {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token'
}
});

API Access Control

  • Configure access rights by selecting user groups
  • Set APIs as public for external access
  • Monitor API usage through logs
  • Track API calls with user information and timestamps

API Testing

SoftyFlow provides built-in API testing capabilities:

  1. Define test variables in JSON format
  2. Use the eye button to test during development
  3. View results in the lower section
  4. Monitor logs for debugging

Best Practices

Security

  • Always validate input data
  • Implement proper authentication
  • Use HTTPS for all API communications
  • Sanitize data before processing

Error Handling

  • Implement comprehensive error handling
  • Return meaningful error messages
  • Log errors for debugging
  • Use appropriate HTTP status codes

Performance

  • Implement request timeouts
  • Use connection pooling where applicable
  • Cache responses when appropriate
  • Monitor API performance

Documentation

  • Document all API endpoints
  • Provide clear examples
  • Maintain version compatibility
  • Update documentation with changes

This comprehensive integration guide enables you to leverage SoftyFlow's full integration capabilities, whether you're consuming external APIs through EDS, making HTTP requests via axios scripts, or exposing SoftyFlow functionality through incoming APIs.