Skip to content

ADR 001

Christian Prior-Mamulyan edited this page Jul 6, 2025 · 1 revision

ADR-001: Typed Internal Models with Custom (De)Serializers for MaestroTaskProcess I/O

Status

Proposed

Context

The MaestroTaskProcess UiPath template is designed to serve as a reusable foundation for RPA workflows invoked as task elements within BPMN processes orchestrated by UiPath Maestro. These workflows are triggered via the “Start and wait for RPA workflow” action and communicate strictly via structured JSON-based arguments:

  • Request (In): required input argument
  • Response (Out): optional business output
  • Status (Out): required metadata/status block

Each of these is governed by a JSON Schema definition:

The question is how to represent and handle these JSON contracts internally within the template: whether to work directly with JSON (e.g. JObject) throughout, or to deserialize them into typed .NET/C#/UiPath data structures.

Decision

We will:

  1. Use typed internal models (Dictionary<string, object> or strongly typed classes) for all core logic.
  2. Leave the deserialization of request.payload to the developer using the template, as its structure is inherently use-case-specific.
  3. Include a stub file (RequestDeserializer.cs) to act as a placeholder and scaffolding point.
  4. Build the Status output using a centralized builder (OutputStatusBuilder) that returns a typed dictionary matching the status-schema.v1.json.
  5. Allow the Result output to be a domain-specific dictionary or typed model, constructed internally and serialized to JSON only at the boundary.
  6. Provide optional ToJObject() or ToJson() methods at boundary points to ensure correct formatting, null handling, and traceability fields.

Rationale

Benefits of this approach:

  • Maintains separation of concerns: orchestration logic is independent of business payload.
  • Improves testability: internal models are easier to unit test, mock, and validate.
  • Supports schema alignment: boundary serializers respect the Maestro contract.
  • Avoids premature generalization: the payload is inherently domain-specific and version-dependent.
  • Aligns with README design principles: especially "API-oriented thinking" and "Structured Outputs".
  • Encourages developer ownership of deserialization, enabling better-fit implementation decisions.

Drawbacks:

  • ⚠ Slightly more complex than using raw JSON (JObject) throughout.
  • ⚠ Requires clear documentation and onboarding for developers to implement their own deserializer.
  • ⚠ Developers might implement this inconsistently unless the template is opinionated via scaffolding and examples.

Alternatives Considered

  • Deserializing payload inside the template: Rejected due to lack of general structure and high risk of overfitting.
  • Using JObject throughout: Would reduce upfront modeling but increase long-term maintenance cost and violate separation of concerns.
  • Returning pre-serialized JSON strings: Rejected due to poor debuggability and lack of type safety.

Consequences

  • The template enforces schema compliance for the outer contract (Request, Result, Status) but leaves payload deserialization as an explicit customization point.
  • A placeholder file (Framework/Adapters/RequestDeserializer.cs) is provided to scaffold this.
  • All outputs remain automatically Maestro-compatible without exposing internal logic to JSON handling intricacies.

Related

  • OutputStatusBuilder.cs: provides status object builders and validators.
  • RequestDeserializer.cs: scaffold file for developer-implemented payload extraction.
  • request-schema.v1.json, response-schema.v1.json, status-schema.v1.json: define contract expectations.
  • README.md Sections 2, 5, 6: describe the template’s API-style, schema-aligned structure.

Owner

Christian Prior-Mamulyan cprior@gmail.com

Clone this wiki locally