elsa-workflows / elsa-workflows/elsa-core

Feature: Extensible Activity Output Converters

Open
#7,770 0 comments 0 reactions 0 assignees View on GitHub
elsa 3 enhancement triaged
Dominant language
C#
Stars
7.9k
Forks
1.5k
Avg merge
15h 22m
Merged PRs (30d)
114

Description

## Summary

Many activities expose outputs in formats that are optimal for the underlying implementation but not always optimal for workflow authors consuming those outputs downstream.

Examples include:

- SQL query results represented as `DataSet`
- XML content represented as strings
- CSV content represented as text
- Binary content represented as `byte[]`

While these output types are valid, workflow designers often require alternative representations that are easier to consume in JavaScript, C#, Python, Liquid, expressions, variables, and custom activities.

---

> Note: While a complete implementation would likely involve Elsa Core, Elsa Studio, and Elsa Extensions, this issue is intended solely to discuss the runtime capability and architectural contract required within Elsa Core. Studio integration and built-in converter implementations can be tracked independently in follow-up issues.

## Problem

Today, if a workflow requires an activity output in a different format, the available options are generally:

- Modify the originating activity implementation.
- Create custom wrapper activities.
- Add dedicated transformation activities after the source activity.
- Implement custom logic repeatedly throughout workflows.

This can result in duplicated transformation logic and additional workflow complexity.

The underlying issue is not specific to any particular activity or module. Any activity may expose outputs in a format that is technically correct but inconvenient for a specific workflow scenario.

---

## Proposed Capability

Introduce support for **optional output converters**.

An output converter would allow an activity output to be transformed into another representation before the output value is bound to a workflow variable.

Conceptually:

```text
Activity Output
|
v
Optional Converter
|
v
Variable / Output Binding
```

The capability should ideally be:

- Opt-in
- Backwards compatible
- Extensible
- Registered through dependency injection
- Applicable to any activity output
- Independent of specific activity implementations

Activities would continue producing their current output types by default.

---

## Example Use Cases

### SQL Query Results

Convert:

```csharp
DataSet
```

to:

```csharp
Dictionary[]
```

This makes the result significantly easier to work with from scripting activities and expressions.

### XML to JSON

Convert:

```xml

1

```

to:

```json
{
"customer": {
"id": 1
}
}
```

### CSV to Object Collection

Convert:

```csv
Id,Name
1,John
2,Sarah
```

to:

```json
[
{
"id": 1,
"name": "John"
},
{
"id": 2,
"name": "Sarah"
}
]
```

### Binary Content Conversion

Convert:

```csharp
byte[]
```

into a workflow-specific type or domain object.

---

## Benefits

- Reduces the need for wrapper activities.
- Encourages reuse of transformation logic.
- Keeps activities focused on their primary responsibilities.
- Allows workflow-specific output preferences.
- Maintains backward compatibility through an opt-in model.
- Provides a consistent conversion mechanism across Elsa modules.

---

## Possible Implementation Direction

One possible implementation approach could be:

- Define output converter contracts within Elsa Core.
- Allow converter implementations to be registered through dependency injection.
- Invoke converters during output binding and variable assignment.
- Expose converter selection through optional UI extensions within Elsa Studio.
- Provide built-in converter implementations through extension modules.

This section is intended only as a discussion starter and not as a strict implementation requirement.

---

## Related Follow-Up Issues

If accepted, this feature would likely require follow-up work in:

- Elsa Studio (converter configuration UI)
- Elsa Extensions (built-in converter implementations)

Contributor guide

Open the contributing guide

Research direction

Start in Elsa Core by tracing output binding and variable assignment, then review the existing dependency-injection registration points. Define the runtime contract for optional, opt-in converters that can apply to any activity output while preserving current output types by default. Done means the Core architectural capability is specified and its boundaries from Elsa Studio and Elsa Extensions are clear.

Written by the indexing model from the issue text.

Assessment

Tech stack
csharp
Domain
backend
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.