Restructure API client

This commit is contained in:
Sipke Schoorstra 2023-05-16 20:03:12 +02:00
parent ad44becbda
commit 3a2b7f40bc
21 changed files with 62 additions and 65 deletions

View file

@ -1,12 +1,14 @@
using Elsa;
using Elsa.EntityFrameworkCore.Extensions;
using Elsa.Extensions;
using Elsa.EntityFrameworkCore.Modules.Labels;
using Elsa.EntityFrameworkCore.Modules.Management;
using Elsa.EntityFrameworkCore.Modules.Runtime;
using Elsa.Http.Handlers;
using Elsa.JavaScript.Options;
using Elsa.WorkflowServer.Web;
EndpointSecurityOptions.DisableSecurity();
var builder = WebApplication.CreateBuilder(args);
var services = builder.Services;
var configuration = builder.Configuration;

View file

@ -1,4 +1,7 @@
namespace Elsa.Api.Client.Contracts;
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Api.Client.Resources.WorkflowInstances.Contracts;
namespace Elsa.Api.Client.Contracts;
/// <summary>
/// Represents a client for the Elsa API. Each API is exposed as a property.

View file

@ -17,4 +17,8 @@
<PackageReference Include="Refit.HttpClientFactory" Version="6.3.2" />
</ItemGroup>
<ItemGroup>
<Folder Include="Resources" />
</ItemGroup>
</Project>

View file

@ -1,5 +1,6 @@
using Elsa.Api.Client.Contracts;
using Elsa.Api.Client.Options;
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Api.Client.Services;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;

View file

@ -1,12 +0,0 @@
namespace Elsa.Api.Client.Contracts;
/// <summary>
/// The request for deleting a workflow definition.
/// </summary>
public class DeleteWorkflowDefinitionRequest
{
/// <summary>
/// The ID of the workflow definition to delete.
/// </summary>
public string DefinitionId { get; set; }
}

View file

@ -1,4 +0,0 @@
namespace Elsa.Api.Client.Contracts;
public record GetWorkflowDefinitionResponse(
);

View file

@ -1,6 +1,7 @@
using Elsa.Api.Client.Models;
using Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
using Refit;
namespace Elsa.Api.Client.Contracts;
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
/// <summary>
/// Represents a client for the workflow definitions API.
@ -13,13 +14,15 @@ public interface IWorkflowDefinitionsApi
/// <param name="request">The request containing options for listing workflow definitions.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The response containing the workflow definitions.</returns>
[Get("/workflow-definitions")]
Task<ListWorkflowDefinitionsResponse> ListAsync(ListWorkflowDefinitionsRequest request, CancellationToken cancellationToken = default);
/// <summary>
/// Deletes a workflow definition.
/// </summary>
/// <param name="request">The request containing the ID of the workflow definition to delete.</param>
/// <param name="definitionId">The ID of the workflow definition to delete.</param>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>The response.</returns>
Task<DeleteWorkflowDefinitionResponse> DeleteAsync(DeleteWorkflowDefinitionRequest request, CancellationToken cancellationToken = default);
[Delete("/workflow-definitions/{definitionId}")]
Task<DeleteWorkflowDefinitionResponse> DeleteAsync(string definitionId, CancellationToken cancellationToken = default);
}

View file

@ -1,4 +1,4 @@
namespace Elsa.Api.Client.Contracts;
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
/// <summary>
/// The response of deleting a workflow definition.

View file

@ -1,4 +1,4 @@
namespace Elsa.Api.Client.Contracts;
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
public class GetWorkflowDefinitionRequest
{

View file

@ -0,0 +1,4 @@
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
public record GetWorkflowDefinitionResponse(
);

View file

@ -1,6 +1,7 @@
using Elsa.Api.Client.Shared.Models;
using Refit;
namespace Elsa.Api.Client.Models;
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
/// <summary>
/// Represents a request to list workflow definitions.

View file

@ -1,4 +1,4 @@
namespace Elsa.Api.Client.Models;
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
/// <summary>
/// Represents a response from listing workflow definitions.

View file

@ -1,6 +1,6 @@
using JetBrains.Annotations;
namespace Elsa.Api.Client.Models;
namespace Elsa.Api.Client.Resources.WorkflowDefinitions.Models;
/// <summary>
/// A summary of a workflow definition.

View file

@ -1,4 +1,4 @@
namespace Elsa.Api.Client.Contracts;
namespace Elsa.Api.Client.Resources.WorkflowInstances.Contracts;
/// <summary>
/// Represents a client for the workflow instances API.

View file

@ -1,4 +1,6 @@
using Elsa.Api.Client.Contracts;
using Elsa.Api.Client.Resources.WorkflowDefinitions.Contracts;
using Elsa.Api.Client.Resources.WorkflowInstances.Contracts;
namespace Elsa.Api.Client.Services;

View file

@ -1,6 +1,6 @@
using JetBrains.Annotations;
namespace Elsa.Api.Client.Models;
namespace Elsa.Api.Client.Shared.Models;
/// <summary>
/// Represents the version to get.

View file

@ -34,7 +34,6 @@
"@stencil/store": "^2.0.6",
"async-mutex": "^0.4.0",
"axios": "^1.4.0",
"axios-middleware": "^0.3.1",
"el-transition": "^0.0.7",
"js-cookie": "^3.0.5",
"jwt-decode": "^3.1.2",

View file

@ -1,6 +1,5 @@
import 'reflect-metadata';
import {h} from "@stencil/core";
import {Service as MiddlewareService} from 'axios-middleware';
import {EventTypes, Plugin} from "../../models";
import {Container, Service} from "typedi";
import {StudioService, AuthContext, EventBus} from "../../services";
@ -27,43 +26,42 @@ export class LoginPlugin implements Plugin {
}
private onHttpClientCreated = async (e) => {
const service: MiddlewareService = e.service;
const axios = e.httpClient;
const loginApi = Container.get(LoginApi);
service.register({
async onRequest(request) {
const authContext = Container.get(AuthContext);
const token = authContext.getAccessToken();
axios.interceptors.request.use(async config => {
const authContext = Container.get(AuthContext);
const token = authContext.getAccessToken();
if (!!token)
request.headers = {...request.headers, Authorization: `Bearer ${token}`};
if (!!token)
config.headers = {...config.headers, Authorization: `Bearer ${token}`};
return request;
},
return config;
});
async onResponseError(error) {
axios.interceptors.response.use(async response => {
return response;
}, async error => {
if (error.response.status !== 401 || error.response.config.hasRetriedRequest)
return;
if (error.response.status !== 401 || error.response.config.hasRetriedRequest)
return;
const authContext = Container.get(AuthContext);
const loginResponse = await loginApi.refreshAccessToken(authContext.getRefreshToken());
const authContext = Container.get(AuthContext);
const loginResponse = await loginApi.refreshAccessToken(authContext.getRefreshToken());
if (loginResponse.isAuthenticated) {
if (loginResponse.isAuthenticated) {
await authContext.updateTokens(loginResponse.accessToken, loginResponse.refreshToken, true);
await authContext.updateTokens(loginResponse.accessToken, loginResponse.refreshToken, true);
return await service.http({
...error.config,
hasRetriedRequest: true,
headers: {
...error.config.headers,
Authorization: `Bearer ${loginResponse.accessToken}`
}
});
} else {
await authContext.signOut();
}
return await axios.request({
...error.config,
hasRetriedRequest: true,
headers: {
...error.config.headers,
Authorization: `Bearer ${loginResponse.accessToken}`
}
});
} else {
await authContext.signOut();
}
});
};

View file

@ -54,8 +54,7 @@ async function createHttpClient(baseAddress: string): Promise<AxiosInstance> {
const eventBus = Container.get(EventBus);
await eventBus.emit(EventTypes.HttpClient.ConfigCreated, this, {config});
const httpClient = axios.create(config);
const middlewareService = new MiddlewareService(httpClient);
await eventBus.emit(EventTypes.HttpClient.ClientCreated, this, {service: middlewareService, httpClient});
await eventBus.emit(EventTypes.HttpClient.ClientCreated, this, {httpClient});
return httpClient;
}

View file

@ -14,7 +14,6 @@
<ItemGroup>
<ProjectReference Include="..\..\common\Elsa.Api.Common\Elsa.Api.Common.csproj" />
<ProjectReference Include="..\Elsa.Identity\Elsa.Identity.csproj" />
</ItemGroup>
</Project>

View file

@ -1,7 +1,6 @@
using Elsa.Abstractions;
using Elsa.Environments.Contracts;
using Elsa.Environments.Models;
using Elsa.Identity;
using JetBrains.Annotations;
namespace Elsa.Environments.Endpoints.Environments.List;
@ -20,7 +19,6 @@ internal class Endpoint : ElsaEndpointWithoutRequest<Response>
{
Get("/environments");
ConfigurePermissions("read:environments");
Policies(IdentityPolicyNames.SecurityRoot);
}
public override async Task<Response> ExecuteAsync(CancellationToken cancellationToken)