aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2024-06-11 22:11:45 -0400
committerLibravatar vnugent <public@vaughnnugent.com>2024-06-11 22:11:45 -0400
commit75c1d0cbf9a5a7856c544671a45f1b4312ffe7ce (patch)
tree788f29e60bc3f431ef2b26c8b84477fe5128d800
parenta7c739b7db9a17622cee751fe0e8a10e4b84b48b (diff)
feat: Add a default site adapater and interceptors
-rw-r--r--lib/Net.Rest.Client/src/Construction/Extensions.cs72
-rw-r--r--lib/Net.Rest.Client/src/Construction/RestSiteAdapterBase.cs46
2 files changed, 91 insertions, 27 deletions
diff --git a/lib/Net.Rest.Client/src/Construction/Extensions.cs b/lib/Net.Rest.Client/src/Construction/Extensions.cs
index 93a1365..7285b84 100644
--- a/lib/Net.Rest.Client/src/Construction/Extensions.cs
+++ b/lib/Net.Rest.Client/src/Construction/Extensions.cs
@@ -30,6 +30,7 @@ using System.Threading.Tasks;
using System.Collections.Generic;
using RestSharp;
+using RestSharp.Interceptors;
namespace VNLib.Net.Rest.Client.Construction
{
@@ -301,13 +302,8 @@ namespace VNLib.Net.Rest.Client.Construction
/// <param name="builder"></param>
/// <param name="withUri">Specifies the uri for the request builder</param>
/// <returns>The chainable <see cref="IRestRequestBuilder{TModel}"/></returns>
- public static IRestRequestBuilder<TModel> WithUrl<TModel>(this IRestRequestBuilder<TModel> builder, Func<TModel, Uri> withUri)
- {
- //Use the supplied method to convert the uri to a string
- builder.WithUrl((m) => withUri(m).ToString());
- return builder;
- }
-
+ public static IRestRequestBuilder<TModel> WithUrl<TModel>(this IRestRequestBuilder<TModel> builder, Func<TModel, Uri> withUri)
+ => builder.WithUrl((m) => withUri(m).ToString());
/// <summary>
/// Sets the uri for all new request messages
@@ -330,12 +326,8 @@ namespace VNLib.Net.Rest.Client.Construction
/// <param name="builder"></param>
/// <param name="url">Specifies the uri for the request builder</param>
/// <returns>The chainable <see cref="IRestRequestBuilder{TModel}"/></returns>
- public static IRestRequestBuilder<TModel> WithUrl<TModel>(this IRestRequestBuilder<TModel> builder, string url)
- {
- //Use the supplied method to convert the uri to a string
- builder.WithUrl((m) => url);
- return builder;
- }
+ public static IRestRequestBuilder<TModel> WithUrl<TModel>(this IRestRequestBuilder<TModel> builder, string url)
+ => builder.WithUrl((m) => url);
/// <summary>
/// Specifies a connection header to set for every request
@@ -345,12 +337,8 @@ namespace VNLib.Net.Rest.Client.Construction
/// <param name="header">The name of the header to set</param>
/// <param name="func">The callback function to get the request header value</param>
/// <returns>The chainable <see cref="IRestRequestBuilder{TModel}"/></returns>
- public static IRestRequestBuilder<TModel> WithHeader<TModel>(this IRestRequestBuilder<TModel> builder, string header, Func<TModel, string> func)
- {
- //Specify a header by the given name
- builder.WithModifier((m, req) => req.AddHeader(header, func(m)));
- return builder;
- }
+ public static IRestRequestBuilder<TModel> WithHeader<TModel>(this IRestRequestBuilder<TModel> builder, string header, Func<TModel, string> func)
+ => builder.WithModifier((m, req) => req.AddHeader(header, func(m)));
/// <summary>
/// Specifies a static connection header to set for every request
@@ -360,11 +348,43 @@ namespace VNLib.Net.Rest.Client.Construction
/// <param name="header">The name of the header to set</param>
/// <param name="value">The static header value to set for all requests</param>
/// <returns>The chainable <see cref="IRestRequestBuilder{TModel}"/></returns>
- public static IRestRequestBuilder<TModel> WithHeader<TModel>(this IRestRequestBuilder<TModel> builder, string header, string value)
+ public static IRestRequestBuilder<TModel> WithHeader<TModel>(this IRestRequestBuilder<TModel> builder, string header, string value)
+ => builder.WithModifier((m, req) => req.AddHeader(header, value));
+
+ /// <summary>
+ /// Adds a client interceptor instance to the request builder
+ /// </summary>
+ /// <typeparam name="TModel"></typeparam>
+ /// <param name="builder"></param>
+ /// <param name="interceptor">A callback function to get an interceptor instance for the builder</param>
+ /// <returns>The chainable <see cref="IRestRequestBuilder{TModel}"/></returns>
+ public static IRestRequestBuilder<TModel> WithInterceptor<TModel>(this IRestRequestBuilder<TModel> builder, Func<TModel, Interceptor> interceptor)
{
- //Specify a header by the given name
- builder.WithModifier((m, req) => req.AddHeader(header, value));
- return builder;
+ ArgumentNullException.ThrowIfNull(interceptor);
+
+ return builder.WithModifier((m, r) =>
+ {
+ r.Interceptors ??= [];
+ r.Interceptors.Add(interceptor(m));
+ });
+ }
+
+ /// <summary>
+ /// Adds a client interceptor instance to the request builder
+ /// </summary>
+ /// <typeparam name="TModel"></typeparam>
+ /// <param name="builder"></param>
+ /// <param name="interceptor">The interceptor instance to add to the request</param>
+ /// <returns>The chainable <see cref="IRestRequestBuilder{TModel}"/></returns>
+ public static IRestRequestBuilder<TModel> WithInterceptor<TModel>(this IRestRequestBuilder<TModel> builder, Interceptor interceptor)
+ {
+ ArgumentNullException.ThrowIfNull(interceptor);
+
+ return builder.WithModifier((m, r) =>
+ {
+ r.Interceptors ??= [];
+ r.Interceptors.Add(interceptor);
+ });
}
/// <summary>
@@ -378,8 +398,7 @@ namespace VNLib.Net.Rest.Client.Construction
public static IRestRequestBuilder<TModel> WithParameter<TModel>(this IRestRequestBuilder<TModel> builder, string parameter, Func<TModel, string> callback)
{
//Get a query item string value from the callback and sets the query paremter
- builder.WithModifier((m, r) => r.AddParameter(parameter, callback(m), ParameterType.GetOrPost));
- return builder;
+ return builder.WithModifier((m, r) => r.AddParameter(parameter, callback(m), ParameterType.GetOrPost));
}
/// <summary>
@@ -393,8 +412,7 @@ namespace VNLib.Net.Rest.Client.Construction
public static IRestRequestBuilder<TModel> WithParameter<TModel>(this IRestRequestBuilder<TModel> builder, string parameter, string value)
{
//Get a query item string value from the callback and sets the query paremter
- builder.WithModifier((m, r) => r.AddParameter(parameter, value, ParameterType.GetOrPost));
- return builder;
+ return builder.WithModifier((m, r) => r.AddParameter(parameter, value, ParameterType.GetOrPost));
}
diff --git a/lib/Net.Rest.Client/src/Construction/RestSiteAdapterBase.cs b/lib/Net.Rest.Client/src/Construction/RestSiteAdapterBase.cs
index f7b234b..4383d51 100644
--- a/lib/Net.Rest.Client/src/Construction/RestSiteAdapterBase.cs
+++ b/lib/Net.Rest.Client/src/Construction/RestSiteAdapterBase.cs
@@ -68,5 +68,51 @@ namespace VNLib.Net.Rest.Client.Construction
/// <typeparam name="TModel">The endpoint model type</typeparam>
/// <param name="adapter">The model typed adapter to add to the store</param>
public virtual void AddAdapter<TModel>(IRestEndpointAdapter<TModel> adapter) => Adapters[typeof(TModel)] = adapter;
+
+ /// <summary>
+ /// Creats a very simple site adapter for simple REST operations with
+ /// your custom rest configuration
+ /// </summary>
+ /// <param name="options">Your custom rest client options</param>
+ /// <param name="maxClients">The maximum number of clients to keep in cached</param>
+ /// <returns>The preconfigured site adapter</returns>
+ public static RestSiteAdapterBase CreateSimpleAdapter(RestClientOptions options, int maxClients = 1)
+ => new SimpleSiteAdapter(maxClients, options);
+
+ /// <summary>
+ /// Creats a very simple site adapter for simple REST operations with
+ /// some basic default options
+ /// </summary>
+ /// <param name="baseUrl">The site base url</param>
+ /// <param name="maxClients">The maximum number of clients to keep in cached</param>
+ /// <returns>The preconfigured site adapter</returns>
+ public static RestSiteAdapterBase CreateSimpleAdapter(string? baseUrl = null, int maxClients = 1)
+ => new SimpleSiteAdapter(maxClients, options: new ()
+ {
+ Encoding = System.Text.Encoding.UTF8,
+ MaxRedirects = 5,
+ BaseUrl = baseUrl is not null ? new Uri(baseUrl) : null,
+ Timeout = TimeSpan.FromSeconds(10),
+ AutomaticDecompression = System.Net.DecompressionMethods.All,
+ AllowMultipleDefaultParametersWithSameName = true,
+ });
+
+ /// <summary>
+ /// Implements an over simplified site adapter for simple REST operations
+ /// </summary>
+ /// <param name="maxClients">The maximum nuber of clients in the connection pool</param>
+ /// <param name="options">The shared client options</param>
+ protected class SimpleSiteAdapter(int maxClients, RestClientOptions options) : RestSiteAdapterBase
+ {
+ ///<inheritdoc/>
+ protected override RestClientPool Pool { get; } = new RestClientPool(maxClients, options);
+
+ ///<inheritdoc/>
+ public override void OnResponse(RestResponse response)
+ { }
+
+ ///<inheritdoc/>
+ public override Task WaitAsync(CancellationToken cancellation = default) => Task.CompletedTask;
+ }
}
}