From dbfb7e7e4779330c5c3e1b2008979cad0876ed28 Mon Sep 17 00:00:00 2001 From: TekH Date: Fri, 16 Jan 2026 11:53:14 +0100 Subject: [PATCH] Refactor API classes to use BaseCrudApi for CRUD ops Introduce BaseCrudApi to encapsulate common CRUD logic for API resource classes. Refactor CommonApi, EndpointAuthApi, EndpointParamsApi, EndpointsApi, ProfileApi, RecActionApi, and ResultApi to inherit from BaseCrudApi, removing duplicated CRUD methods and constructors. This centralizes CRUD operations, reduces code duplication, and improves maintainability. --- src/ReC.Client/Api/BaseCrudApi.cs | 71 +++++++++++++++++++++++++ src/ReC.Client/Api/CommonApi.cs | 43 +-------------- src/ReC.Client/Api/EndpointAuthApi.cs | 44 +-------------- src/ReC.Client/Api/EndpointParamsApi.cs | 44 +-------------- src/ReC.Client/Api/EndpointsApi.cs | 44 +-------------- src/ReC.Client/Api/ProfileApi.cs | 46 ++-------------- src/ReC.Client/Api/RecActionApi.cs | 48 ++--------------- src/ReC.Client/Api/ResultApi.cs | 46 ++-------------- 8 files changed, 89 insertions(+), 297 deletions(-) create mode 100644 src/ReC.Client/Api/BaseCrudApi.cs diff --git a/src/ReC.Client/Api/BaseCrudApi.cs b/src/ReC.Client/Api/BaseCrudApi.cs new file mode 100644 index 0000000..cce0594 --- /dev/null +++ b/src/ReC.Client/Api/BaseCrudApi.cs @@ -0,0 +1,71 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; + +namespace ReC.Client.Api +{ + /// + /// Provides shared CRUD operations for API resources. + /// + public abstract class BaseCrudApi + { + /// + /// The HTTP client used to send requests. + /// + protected readonly HttpClient Http; + + /// + /// The base resource path for the API endpoint. + /// + protected readonly string ResourcePath; + + /// + /// Initializes a new instance of the class. + /// + /// The HTTP client used for requests. + /// The base resource path for the API endpoint. + protected BaseCrudApi(HttpClient http, string resourcePath) + { + Http = http ?? throw new ArgumentNullException(nameof(http)); + ResourcePath = resourcePath ?? throw new ArgumentNullException(nameof(resourcePath)); + } + + /// + /// Creates a resource. + /// + /// The payload type. + /// The payload to send. + /// A token to cancel the operation. + /// The HTTP response message. + public Task CreateAsync(T payload, CancellationToken cancel = default) + => Http.PostAsync(ResourcePath, ReCClientHelpers.ToJsonContent(payload), cancel); + + /// + /// Updates a resource by identifier. + /// + /// The payload type. + /// The resource identifier. + /// The payload to send. + /// A token to cancel the operation. + /// The HTTP response message. + public Task UpdateAsync(long id, T payload, CancellationToken cancel = default) + => Http.PutAsync($"{ResourcePath}/{id}", ReCClientHelpers.ToJsonContent(payload), cancel); + + /// + /// Deletes resources with identifiers supplied in the payload. + /// + /// The payload type containing identifiers. + /// The payload to send. + /// A token to cancel the operation. + /// The HTTP response message. + public Task DeleteAsync(T payload, CancellationToken cancel = default) + { + var request = new HttpRequestMessage(HttpMethod.Delete, ResourcePath) + { + Content = ReCClientHelpers.ToJsonContent(payload) + }; + return Http.SendAsync(request, cancel); + } + } +} diff --git a/src/ReC.Client/Api/CommonApi.cs b/src/ReC.Client/Api/CommonApi.cs index 5dd4f1a..aea3cdf 100644 --- a/src/ReC.Client/Api/CommonApi.cs +++ b/src/ReC.Client/Api/CommonApi.cs @@ -7,53 +7,14 @@ namespace ReC.Client.Api /// /// Provides access to common object endpoints. /// - public class CommonApi + public class CommonApi : BaseCrudApi { - private readonly HttpClient _http; - /// /// Initializes a new instance of the class. /// /// The HTTP client used for requests. - public CommonApi(HttpClient http) - { - _http = http; - } - - /// - /// Creates an object. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task CreateAsync(T procedure, CancellationToken cancel = default) - => _http.PostAsync("api/Common", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Updates an object. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task UpdateAsync(T procedure, CancellationToken cancel = default) - => _http.PutAsync("api/Common", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Deletes objects. - /// - /// The payload type containing identifiers. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task DeleteAsync(T procedure, CancellationToken cancel = default) + public CommonApi(HttpClient http) : base(http, "api/Common") { - var request = new HttpRequestMessage(HttpMethod.Delete, "api/Common") - { - Content = ReCClientHelpers.ToJsonContent(procedure) - }; - return _http.SendAsync(request, cancel); } } } diff --git a/src/ReC.Client/Api/EndpointAuthApi.cs b/src/ReC.Client/Api/EndpointAuthApi.cs index e583bbd..287d6d0 100644 --- a/src/ReC.Client/Api/EndpointAuthApi.cs +++ b/src/ReC.Client/Api/EndpointAuthApi.cs @@ -7,54 +7,14 @@ namespace ReC.Client.Api /// /// Provides access to endpoint authentication endpoints. /// - public class EndpointAuthApi + public class EndpointAuthApi : BaseCrudApi { - private readonly HttpClient _http; - /// /// Initializes a new instance of the class. /// /// The HTTP client used for requests. - public EndpointAuthApi(HttpClient http) - { - _http = http; - } - - /// - /// Creates endpoint authentication configuration. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task CreateAsync(T procedure, CancellationToken cancel = default) - => _http.PostAsync("api/EndpointAuth", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Updates endpoint authentication configuration. - /// - /// The payload type. - /// The authentication identifier. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task UpdateAsync(long id, T procedure, CancellationToken cancel = default) - => _http.PutAsync($"api/EndpointAuth/{id}", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Deletes endpoint authentications. - /// - /// The payload type containing identifiers. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task DeleteAsync(T procedure, CancellationToken cancel = default) + public EndpointAuthApi(HttpClient http) : base(http, "api/EndpointAuth") { - var request = new HttpRequestMessage(HttpMethod.Delete, "api/EndpointAuth") - { - Content = ReCClientHelpers.ToJsonContent(procedure) - }; - return _http.SendAsync(request, cancel); } } } diff --git a/src/ReC.Client/Api/EndpointParamsApi.cs b/src/ReC.Client/Api/EndpointParamsApi.cs index 0cd96e5..ac7b781 100644 --- a/src/ReC.Client/Api/EndpointParamsApi.cs +++ b/src/ReC.Client/Api/EndpointParamsApi.cs @@ -7,54 +7,14 @@ namespace ReC.Client.Api /// /// Provides access to endpoint parameter endpoints. /// - public class EndpointParamsApi + public class EndpointParamsApi : BaseCrudApi { - private readonly HttpClient _http; - /// /// Initializes a new instance of the class. /// /// The HTTP client used for requests. - public EndpointParamsApi(HttpClient http) - { - _http = http; - } - - /// - /// Creates endpoint parameters. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task CreateAsync(T procedure, CancellationToken cancel = default) - => _http.PostAsync("api/EndpointParams", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Updates endpoint parameters. - /// - /// The payload type. - /// The parameter identifier. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task UpdateAsync(long id, T procedure, CancellationToken cancel = default) - => _http.PutAsync($"api/EndpointParams/{id}", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Deletes endpoint parameters. - /// - /// The payload type containing identifiers. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task DeleteAsync(T procedure, CancellationToken cancel = default) + public EndpointParamsApi(HttpClient http) : base(http, "api/EndpointParams") { - var request = new HttpRequestMessage(HttpMethod.Delete, "api/EndpointParams") - { - Content = ReCClientHelpers.ToJsonContent(procedure) - }; - return _http.SendAsync(request, cancel); } } } diff --git a/src/ReC.Client/Api/EndpointsApi.cs b/src/ReC.Client/Api/EndpointsApi.cs index 015434c..cc8634e 100644 --- a/src/ReC.Client/Api/EndpointsApi.cs +++ b/src/ReC.Client/Api/EndpointsApi.cs @@ -7,54 +7,14 @@ namespace ReC.Client.Api /// /// Provides access to endpoint definitions. /// - public class EndpointsApi + public class EndpointsApi : BaseCrudApi { - private readonly HttpClient _http; - /// /// Initializes a new instance of the class. /// /// The HTTP client used for requests. - public EndpointsApi(HttpClient http) - { - _http = http; - } - - /// - /// Creates an endpoint. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task CreateAsync(T procedure, CancellationToken cancel = default) - => _http.PostAsync("api/Endpoints", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Updates an endpoint. - /// - /// The payload type. - /// The endpoint identifier. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task UpdateAsync(long id, T procedure, CancellationToken cancel = default) - => _http.PutAsync($"api/Endpoints/{id}", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Deletes endpoints. - /// - /// The payload type containing identifiers. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task DeleteAsync(T procedure, CancellationToken cancel = default) + public EndpointsApi(HttpClient http) : base(http, "api/Endpoints") { - var request = new HttpRequestMessage(HttpMethod.Delete, "api/Endpoints") - { - Content = ReCClientHelpers.ToJsonContent(procedure) - }; - return _http.SendAsync(request, cancel); } } } diff --git a/src/ReC.Client/Api/ProfileApi.cs b/src/ReC.Client/Api/ProfileApi.cs index e27ab68..a2f6827 100644 --- a/src/ReC.Client/Api/ProfileApi.cs +++ b/src/ReC.Client/Api/ProfileApi.cs @@ -7,17 +7,14 @@ namespace ReC.Client.Api /// /// Provides access to profile endpoints. /// - public class ProfileApi + public class ProfileApi : BaseCrudApi { - private readonly HttpClient _http; - /// /// Initializes a new instance of the class. /// /// The HTTP client used for requests. - public ProfileApi(HttpClient http) + public ProfileApi(HttpClient http) : base(http, "api/Profile") { - _http = http; } /// @@ -30,44 +27,7 @@ namespace ReC.Client.Api public Task GetAsync(long id, bool includeActions = false, CancellationToken cancel = default) { var query = ReCClientHelpers.BuildQuery(("Id", id), ("IncludeActions", includeActions)); - return _http.GetAsync($"api/Profile{query}", cancel); - } - - /// - /// Creates a profile. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task CreateAsync(T procedure, CancellationToken cancel = default) - => _http.PostAsync("api/Profile", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Updates a profile. - /// - /// The payload type. - /// The profile identifier. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task UpdateAsync(long id, T procedure, CancellationToken cancel = default) - => _http.PutAsync($"api/Profile/{id}", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Deletes profiles. - /// - /// The payload type containing identifiers. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task DeleteAsync(T procedure, CancellationToken cancel = default) - { - var request = new HttpRequestMessage(HttpMethod.Delete, "api/Profile") - { - Content = ReCClientHelpers.ToJsonContent(procedure) - }; - return _http.SendAsync(request, cancel); + return Http.GetAsync($"{ResourcePath}{query}", cancel); } } } diff --git a/src/ReC.Client/Api/RecActionApi.cs b/src/ReC.Client/Api/RecActionApi.cs index b1025f6..830c76d 100644 --- a/src/ReC.Client/Api/RecActionApi.cs +++ b/src/ReC.Client/Api/RecActionApi.cs @@ -7,17 +7,14 @@ namespace ReC.Client.Api /// /// Provides access to RecAction endpoints. /// - public class RecActionApi + public class RecActionApi : BaseCrudApi { - private readonly HttpClient _http; - /// /// Initializes a new instance of the class. /// /// The HTTP client used for requests. - public RecActionApi(HttpClient http) + public RecActionApi(HttpClient http) : base(http, "api/RecAction") { - _http = http; } /// @@ -28,7 +25,7 @@ namespace ReC.Client.Api /// if the request succeeds; otherwise, . public async Task InvokeAsync(int profileId, CancellationToken cancellationToken = default) { - var resp = await _http.PostAsync($"api/RecAction/invoke/{profileId}", content: null, cancellationToken); + var resp = await Http.PostAsync($"{ResourcePath}/invoke/{profileId}", content: null, cancellationToken); return resp.IsSuccessStatusCode; } @@ -42,44 +39,7 @@ namespace ReC.Client.Api public Task GetAsync(long? profileId = null, bool? invoked = null, CancellationToken cancel = default) { var query = ReCClientHelpers.BuildQuery(("ProfileId", profileId), ("Invoked", invoked)); - return _http.GetAsync($"api/RecAction{query}", cancel); - } - - /// - /// Creates a Rec action. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task CreateAsync(T procedure, CancellationToken cancel = default) - => _http.PostAsync("api/RecAction", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Updates a Rec action. - /// - /// The payload type. - /// The action identifier. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task UpdateAsync(long id, T procedure, CancellationToken cancel = default) - => _http.PutAsync($"api/RecAction/{id}", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Deletes Rec actions. - /// - /// The payload type containing identifiers. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task DeleteAsync(T procedure, CancellationToken cancel = default) - { - var request = new HttpRequestMessage(HttpMethod.Delete, "api/RecAction") - { - Content = ReCClientHelpers.ToJsonContent(procedure) - }; - return _http.SendAsync(request, cancel); + return Http.GetAsync($"{ResourcePath}{query}", cancel); } } } diff --git a/src/ReC.Client/Api/ResultApi.cs b/src/ReC.Client/Api/ResultApi.cs index bf4f308..37dca07 100644 --- a/src/ReC.Client/Api/ResultApi.cs +++ b/src/ReC.Client/Api/ResultApi.cs @@ -7,17 +7,14 @@ namespace ReC.Client.Api /// /// Provides access to output result endpoints. /// - public class ResultApi + public class ResultApi : BaseCrudApi { - private readonly HttpClient _http; - /// /// Initializes a new instance of the class. /// /// The HTTP client used for requests. - public ResultApi(HttpClient http) + public ResultApi(HttpClient http) : base(http, "api/Result") { - _http = http; } /// @@ -31,44 +28,7 @@ namespace ReC.Client.Api public Task GetAsync(long? id = null, long? actionId = null, long? profileId = null, CancellationToken cancel = default) { var query = ReCClientHelpers.BuildQuery(("Id", id), ("ActionId", actionId), ("ProfileId", profileId)); - return _http.GetAsync($"api/Result{query}", cancel); - } - - /// - /// Creates a result. - /// - /// The payload type. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task CreateAsync(T procedure, CancellationToken cancel = default) - => _http.PostAsync("api/Result", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Updates a result. - /// - /// The payload type. - /// The result identifier. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task UpdateAsync(long id, T procedure, CancellationToken cancel = default) - => _http.PutAsync($"api/Result/{id}", ReCClientHelpers.ToJsonContent(procedure), cancel); - - /// - /// Deletes results. - /// - /// The payload type containing identifiers. - /// The payload to send. - /// A token to cancel the operation. - /// The HTTP response message. - public Task DeleteAsync(T procedure, CancellationToken cancel = default) - { - var request = new HttpRequestMessage(HttpMethod.Delete, "api/Result") - { - Content = ReCClientHelpers.ToJsonContent(procedure) - }; - return _http.SendAsync(request, cancel); + return Http.GetAsync($"{ResourcePath}{query}", cancel); } } }