Add endpoint to get workflow definition by ID

This commit is contained in:
Sipke Schoorstra 2023-07-06 14:20:36 +02:00
parent fdf71a4141
commit 259785144c
7 changed files with 91 additions and 11 deletions

View file

@ -22,14 +22,23 @@ public interface IWorkflowDefinitionsApi
Task<ListWorkflowDefinitionsResponse> ListAsync([Query]ListWorkflowDefinitionsRequest request, [Query]VersionOptions? versionOptions = default, CancellationToken cancellationToken = default);
/// <summary>
/// Gets a workflow definition.
/// Gets a workflow definition by definition ID.
/// </summary>
/// <param name="definitionId">The ID of the workflow definition to get.</param>
/// <param name="definitionId">The definition ID of the workflow definition to get.</param>
/// <param name="versionOptions">The version options.</param>
/// <param name="includeCompositeRoot">Whether to include the root activity of composite activities.</param>
/// <param name="cancellationToken">The cancellation token.</param>
[Get("/workflow-definitions/{definitionId}?versionOptions={versionOptions}&includeCompositeRoot={includeCompositeRoot}")]
Task<WorkflowDefinition?> GetAsync(string definitionId, VersionOptions? versionOptions = default, bool includeCompositeRoot = false, CancellationToken cancellationToken = default);
[Get("/workflow-definitions/by-definition-id/{definitionId}?versionOptions={versionOptions}&includeCompositeRoot={includeCompositeRoot}")]
Task<WorkflowDefinition?> GetByDefinitionIdAsync(string definitionId, VersionOptions? versionOptions = default, bool includeCompositeRoot = false, CancellationToken cancellationToken = default);
/// <summary>
/// Gets a workflow definition by ID.
/// </summary>
/// <param name="id">The ID of the workflow definition to get.</param>
/// <param name="includeCompositeRoot">Whether to include the root activity of composite activities.</param>
/// <param name="cancellationToken">The cancellation token.</param>
[Get("/workflow-definitions/by-id/{id}?includeCompositeRoot={includeCompositeRoot}")]
Task<WorkflowDefinition?> GetByIdAsync(string id, bool includeCompositeRoot = false, CancellationToken cancellationToken = default);
/// <summary>
/// Gets the number of workflow definitions.

View file

@ -6,17 +6,19 @@ using Elsa.Workflows.Core.Serialization.Converters;
using Elsa.Workflows.Management.Contracts;
using Elsa.Workflows.Management.Filters;
using Elsa.Workflows.Management.Mappers;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Get;
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.GetByDefinitionId;
internal class Get : ElsaEndpoint<Request>
[PublicAPI]
internal class GetByDefinitionId : ElsaEndpoint<Request>
{
private readonly IWorkflowDefinitionStore _store;
private readonly IApiSerializer _apiSerializer;
private readonly WorkflowDefinitionMapper _mapper;
public Get(IWorkflowDefinitionStore store, IApiSerializer apiSerializer, WorkflowDefinitionMapper mapper)
public GetByDefinitionId(IWorkflowDefinitionStore store, IApiSerializer apiSerializer, WorkflowDefinitionMapper mapper)
{
_store = store;
_apiSerializer = apiSerializer;
@ -25,7 +27,7 @@ internal class Get : ElsaEndpoint<Request>
public override void Configure()
{
Get("/workflow-definitions/{definitionId}");
Get("/workflow-definitions/by-definition-id/{definitionId}", "/workflow-definitions/{definitionId}");
ConfigurePermissions("read:workflow-definitions");
}

View file

@ -1,4 +1,4 @@
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.Get;
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.GetByDefinitionId;
internal class Request
{

View file

@ -0,0 +1,58 @@
using Elsa.Abstractions;
using Elsa.Common.Entities;
using Elsa.Common.Models;
using Elsa.Workflows.Core.Contracts;
using Elsa.Workflows.Core.Serialization.Converters;
using Elsa.Workflows.Management.Contracts;
using Elsa.Workflows.Management.Filters;
using Elsa.Workflows.Management.Mappers;
using JetBrains.Annotations;
using Microsoft.AspNetCore.Http;
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.GetById;
[PublicAPI]
internal class GetById : ElsaEndpoint<Request>
{
private readonly IWorkflowDefinitionStore _store;
private readonly IApiSerializer _apiSerializer;
private readonly WorkflowDefinitionMapper _mapper;
public GetById(IWorkflowDefinitionStore store, IApiSerializer apiSerializer, WorkflowDefinitionMapper mapper)
{
_store = store;
_apiSerializer = apiSerializer;
_mapper = mapper;
}
public override void Configure()
{
Get("/workflow-definitions/by-id/{id}");
ConfigurePermissions("read:workflow-definitions");
}
public override async Task HandleAsync(Request request, CancellationToken cancellationToken)
{
var filter = new WorkflowDefinitionFilter
{
Id = request.Id
};
var definition = (await _store.FindManyAsync(filter, cancellationToken)).FirstOrDefault();
if (definition == null)
{
await SendNotFoundAsync(cancellationToken);
return;
}
var model = await _mapper.MapAsync(definition, cancellationToken);
var serializerOptions = _apiSerializer.CreateOptions();
// If the root of composite activities is not requested, exclude them from being serialized.
if (!request.IncludeCompositeRoot)
serializerOptions.Converters.Add(new JsonIgnoreCompositeRootConverterFactory());
await HttpContext.Response.WriteAsJsonAsync(model, serializerOptions, cancellationToken);
}
}

View file

@ -0,0 +1,11 @@
namespace Elsa.Workflows.Api.Endpoints.WorkflowDefinitions.GetById;
internal class Request
{
public string Id { get; set; } = default!;
/// <summary>
/// True if the response should include the root activity of composite activities.
/// </summary>
public bool IncludeCompositeRoot { get; set; }
}

View file

@ -53,7 +53,7 @@ internal class Import : ElsaEndpoint<WorkflowDefinitionModel, WorkflowDefinition
var updatedModel = await _workflowDefinitionMapper.MapAsync(draft, cancellationToken);
if (isNew)
await SendCreatedAtAsync<Get.Get>(new { DefinitionId = definitionId }, updatedModel, cancellation: cancellationToken);
await SendCreatedAtAsync<GetByDefinitionId.GetByDefinitionId>(new { DefinitionId = definitionId }, updatedModel, cancellation: cancellationToken);
else
await SendOkAsync(updatedModel, cancellationToken);
}

View file

@ -95,7 +95,7 @@ internal class Post : ElsaEndpoint<SaveWorkflowDefinitionRequest, WorkflowDefini
var response = await _workflowDefinitionMapper.MapAsync(draft, cancellationToken);
if (isNew)
await SendCreatedAtAsync<Get.Get>(new { definitionId }, response, cancellation: cancellationToken);
await SendCreatedAtAsync<GetByDefinitionId.GetByDefinitionId>(new { definitionId }, response, cancellation: cancellationToken);
else
{
await HttpContext.Response.WriteAsJsonAsync(response, serializerOptions, cancellationToken);