Skip to content

Commit

Permalink
Modified POST Execute API to Display Body in Swagger and Fixed Type-C…
Browse files Browse the repository at this point in the history
…asting Error in GET Execute API (#5858)

* Modified POST execute API to show body in Swagger and resolved type-casting error in GET execute API

Modified the POST execute API to display the body in Swagger documentation and resolved the type-casting error in the GET execute API

* Added IExecutionRequest interface defines a contract for Request classes

* Moved the serialization logic into request classes

* Add missing import and reformat ActivityHandle property

Included the Elsa.Workflows.Models import in Models.cs to fix missing reference. Removed redundant ActivityHandle assignment in EndpointBase.cs to improve clarity and reduce redundancy.

---------

Co-authored-by: Sipke Schoorstra <[email protected]>
  • Loading branch information
cvijayak and sfmskywalker committed Aug 16, 2024
1 parent ba06811 commit 2b22400
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,31 +7,29 @@
using Elsa.Workflows.Runtime;
using Elsa.Workflows.Runtime.Messages;
using Elsa.Workflows.State;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;

namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Execute;

/// <summary>
/// An API endpoint that executes a given workflow definition.
/// This abstract class provides the necessary infrastructure to handle the execution of workflows, including setup of routes, permissions,
/// and processing of HTTP requests to execute workflows.
/// </summary>
[PublicAPI]
internal class Execute(
internal abstract class EndpointBase<T>(
IWorkflowDefinitionService workflowDefinitionService,
IWorkflowRuntime workflowRuntime,
IApiSerializer apiSerializer)
: ElsaEndpoint<Request, Response>
: ElsaEndpoint<T, Response> where T : IExecutionRequest, new()
{
/// <inheritdoc />
public override void Configure()
{
Routes("/workflow-definitions/{definitionId}/execute");
Verbs(FastEndpoints.Http.GET, FastEndpoints.Http.POST);
ConfigurePermissions("exec:workflow-definitions");
}

/// <inheritdoc />
public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
public override async Task HandleAsync(T request, CancellationToken cancellationToken)
{
var definitionId = request.DefinitionId;
var versionOptions = request.VersionOptions ?? VersionOptions.Published;
Expand All @@ -48,7 +46,7 @@ public override async Task HandleAsync(Request request, CancellationToken cancel
{
WorkflowDefinitionHandle = WorkflowDefinitionHandle.ByDefinitionVersionId(workflowGraph.Workflow.Identity.Id),
CorrelationId = request.CorrelationId,
Input = (IDictionary<string, object>?)request.Input,
Input = request.GetInputAsDictionary(),
TriggerActivityId = request.TriggerActivityId,
ActivityHandle = request.ActivityHandle
};
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Management;
using Elsa.Workflows.Runtime;
using JetBrains.Annotations;

namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Execute;

/// <summary>
/// An API endpoint that executes a given workflow definition through GET method.
/// </summary>
[PublicAPI]
internal class GetEndpoint(
IWorkflowDefinitionService workflowDefinitionService,
IWorkflowRuntime workflowRuntime,
IApiSerializer apiSerializer)
: EndpointBase<GetRequest>(workflowDefinitionService, workflowRuntime, apiSerializer)
{
/// <inheritdoc />
public override void Configure()
{
base.Configure();
Verbs(FastEndpoints.Http.GET);
}
}
Original file line number Diff line number Diff line change
@@ -1,22 +1,60 @@
using System.Dynamic;
using System.Text.Json;
using System.Text.Json.Serialization;
using Elsa.Common.Models;
using Elsa.Expressions.Helpers;
using Elsa.Workflows.Models;
using Elsa.Workflows.Serialization.Converters;
using Elsa.Workflows.State;

namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Execute;

public class Request
public interface IExecutionRequest
{
string DefinitionId { get; }
string? CorrelationId { get; }
string? TriggerActivityId { get; }
ActivityHandle? ActivityHandle { get; }
VersionOptions? VersionOptions { get; }

IDictionary<string, object>? GetInputAsDictionary();
}

public class PostRequest : IExecutionRequest
{
public string DefinitionId { get; set; } = default!;
public string? CorrelationId { get; set; }
public string? TriggerActivityId { get; set; }
public ActivityHandle? ActivityHandle { get; set; }

public VersionOptions? VersionOptions { get; set; }

[JsonConverter(typeof(ExpandoObjectConverterFactory))]
public object? Input { get; set; }

public IDictionary<string, object>? GetInputAsDictionary() => (IDictionary<string, object>?)Input;
}

public class GetRequest : IExecutionRequest
{
public string DefinitionId { get; set; } = default!;
public string? CorrelationId { get; set; }
public string? TriggerActivityId { get; set; }
public ActivityHandle? ActivityHandle { get; set; }
public VersionOptions? VersionOptions { get; set; }
public string? Input { get; set; }

public IDictionary<string, object>? GetInputAsDictionary()
{
var result = Input?.TryConvertTo<ExpandoObject>(new ObjectConverterOptions
{
SerializerOptions = new JsonSerializerOptions
{
Converters = { new ExpandoObjectConverter() }
}
});

return result?.Success == true ? (IDictionary<string, object>?)result.Value : null;
}
}

public class Response(WorkflowState workflowState)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Elsa.Workflows.Contracts;
using Elsa.Workflows.Management;
using Elsa.Workflows.Runtime;
using JetBrains.Annotations;

namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Execute;

/// <summary>
/// An API endpoint that executes a given workflow definition through POST method.
/// </summary>
[PublicAPI]
internal class PostEndpoint(
IWorkflowDefinitionService workflowDefinitionService,
IWorkflowRuntime workflowRuntime,
IApiSerializer apiSerializer)
: EndpointBase<PostRequest>(workflowDefinitionService, workflowRuntime, apiSerializer)
{
/// <inheritdoc />
public override void Configure()
{
base.Configure();
Verbs(FastEndpoints.Http.POST);
}
}

0 comments on commit 2b22400

Please sign in to comment.