Skip to content

Commit

Permalink
perf(logging): middleware loggings changed to compile-time logging + …
Browse files Browse the repository at this point in the history
…deprecated cleanup and minor imp (#85)

### Performance
- **logging:** middleware loggings changed to compile-time logging
- **request builder:** uri interpolation regex compile-time

### BREAKING CHANGES
- **http request:** remove deprecated `FluentHttpRequest.Formatters`
- **models:** change several options/context models to `record`'s
  • Loading branch information
stephenlautier authored Jul 24, 2024
1 parent 9fde35c commit 3a5764f
Show file tree
Hide file tree
Showing 26 changed files with 144 additions and 204 deletions.
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,21 @@

[_vNext_](https://github.com/sketch7/FluentlyHttpClient/compare/3.8.1...3.9.0) (2020-X-X)

## [4.0.0](https://github.com/sketch7/FluentlyHttpClient/compare/3.9.6...4.0.0) (2024-07-23)
## [4.0.0](https://github.com/sketch7/FluentlyHttpClient/compare/3.9.6...4.0.0) (2024-07-24)

### Features
- **http client builder:** configurable http version/policy via `WithVersion`, `WithVersionPolicy`
- **http client builder:** defaults to http version http2.0

### Performance
- **logging:** middleware loggings changed to compile-time logging
- **request builder:** uri interpolation regex compile-time

### BREAKING CHANGES

- **deps:** now target .net8
- **http request:** remove deprecated `FluentHttpRequest.Formatters`
- **models:** change several options/context models to `record`'s

## [3.9.6](https://github.com/sketch7/FluentlyHttpClient/compare/3.9.5...3.9.6) (2024-06-11)

Expand Down
10 changes: 5 additions & 5 deletions src/FluentlyHttpClient/Caching/HttpResponseSerializer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public class HttpResponseSerializer : IHttpResponseSerializer
Hash = response.GetRequestHash(),
ReasonPhrase = response.ReasonPhrase,
StatusCode = (int)response.StatusCode,
Url = response.Message.RequestMessage.RequestUri.ToString(),
Url = response.Message.RequestMessage!.RequestUri!.ToString(),
Version = response.Message.Version.ToString(),
Headers = new(response.Headers),
RequestMessage = response.Message.RequestMessage
Expand All @@ -43,18 +43,18 @@ public class HttpResponseSerializer : IHttpResponseSerializer
/// <returns></returns>
public Task<FluentHttpResponse> Deserialize(IHttpResponseStore item)
{
var contentType = new ContentType(item.ContentHeaders.ContentType);
var contentType = new ContentType(item.ContentHeaders!.ContentType!);
var encoding = string.IsNullOrEmpty(contentType.CharSet) ? Encoding.UTF8 : Encoding.GetEncoding(contentType.CharSet);

var cloned = new FluentHttpResponse(new((HttpStatusCode)item.StatusCode)
{
Content = new StringContent(item.Content, encoding, contentType.MediaType),
Content = new StringContent(item.Content!, encoding, contentType.MediaType),
ReasonPhrase = item.ReasonPhrase,
Version = new(item.Version),
Version = new(item.Version!),
RequestMessage = item.RequestMessage,
}); // todo: add items?

cloned.Headers.AddRange(item.Headers);
cloned.Headers.AddRange(item.Headers!);

return Task.FromResult(cloned);
}
Expand Down
8 changes: 4 additions & 4 deletions src/FluentlyHttpClient/FluentHttpClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public interface IFluentHttpClient : IDisposable
/// <summary>
/// Gets the default formatter to be used when serializing body content. e.g. JSON, XML, etc...
/// </summary>
MediaTypeFormatter DefaultFormatter { get; }
MediaTypeFormatter? DefaultFormatter { get; }

/// <summary>Get the formatter for an HTTP content type.</summary>
/// <param name="contentType">The HTTP content type (or <c>null</c> to automatically select one).</param>
Expand Down Expand Up @@ -102,7 +102,7 @@ public class FluentHttpClient : IFluentHttpClient
public MediaTypeFormatterCollection Formatters { get; }

/// <inheritdoc />
public MediaTypeFormatter DefaultFormatter { get; }
public MediaTypeFormatter? DefaultFormatter { get; }

/// <inheritdoc />
public HttpRequestHeaders Headers { get; }
Expand Down Expand Up @@ -175,7 +175,7 @@ public FluentHttpRequestBuilder CreateRequest(string? uriTemplate = null, object
/// <inheritdoc />
public async Task<FluentHttpResponse> Send(FluentHttpRequest request)
{
if (request == null) throw new ArgumentNullException(nameof(request));
ArgumentNullException.ThrowIfNull(request, nameof(request));

var requestId = request.Message.AddRequestId();

Expand All @@ -193,7 +193,7 @@ public async Task<FluentHttpResponse> Send(FluentHttpRequest request)

public async Task<FluentHttpResponse> Send(HttpRequestMessage request)
{
if (request == null) throw new ArgumentNullException(nameof(request));
ArgumentNullException.ThrowIfNull(request, nameof(request));

var requestId = request.AddRequestId();
await RawHttpClient.SendAsync(request);
Expand Down
12 changes: 3 additions & 9 deletions src/FluentlyHttpClient/FluentHttpClientBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ public class FluentHttpClientBuilder : IFluentHttpHeaderBuilder<FluentHttpClient
/// <summary>
/// Gets the identifier specified.
/// </summary>
public string? Identifier { get; private set; }
public string Identifier { get; private set; } = null!;

private readonly IServiceProvider _serviceProvider;
private readonly IFluentHttpClientFactory _fluentHttpClientFactory;
private readonly FluentHttpMiddlewareBuilder _middlewareBuilder;
private string? _baseUrl;
private TimeSpan _timeout;
private readonly FluentHttpHeaders _headers = new();
private readonly FluentHttpHeaders _headers = [];
private Action<FluentHttpRequestBuilder>? _requestBuilderDefaults;
private HttpMessageHandler? _httpMessageHandler;
private readonly FormatterOptions _formatterOptions = new();
Expand Down Expand Up @@ -73,42 +73,36 @@ public FluentHttpClientBuilder WithTimeout(TimeSpan timeout)
return this;
}

/// <inheritdoc />
public FluentHttpClientBuilder WithHeader(string key, string value)
{
_headers.Set(key, value);
return this;
}

/// <inheritdoc />
public FluentHttpClientBuilder WithHeader(string key, StringValues values)
{
_headers.Set(key, values);
return this;
}

/// <inheritdoc />
public FluentHttpClientBuilder WithHeaders(IDictionary<string, string> headers)
{
_headers.SetRange(headers);
return this;
}

/// <inheritdoc />
public FluentHttpClientBuilder WithHeaders(IDictionary<string, string[]> headers)
{
_headers.SetRange(headers);
return this;
}

/// <inheritdoc />
public FluentHttpClientBuilder WithHeaders(IDictionary<string, StringValues> headers)
{
_headers.SetRange(headers);
return this;
}

/// <inheritdoc />
public FluentHttpClientBuilder WithHeaders(FluentHttpHeaders headers)
{
_headers.SetRange(headers);
Expand Down Expand Up @@ -287,7 +281,7 @@ internal class MediaTypeFormatterComparer : IEqualityComparer<MediaTypeFormatter
{
public static readonly MediaTypeFormatterComparer Instance = new();

public bool Equals(MediaTypeFormatter x, MediaTypeFormatter y) => x?.GetType() == y?.GetType();
public bool Equals(MediaTypeFormatter? x, MediaTypeFormatter? y) => x?.GetType() == y?.GetType();

public int GetHashCode(MediaTypeFormatter obj) => obj.GetType().GetHashCode();
}
10 changes: 5 additions & 5 deletions src/FluentlyHttpClient/FluentHttpClientOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ public class FluentHttpClientOptions
/// <summary>
/// Gets or sets the identifier (key) for the HTTP client.
/// </summary>
public string? Identifier { get; set; }
public string Identifier { get; set; } = null!;

/// <summary>
/// Gets or sets the headers which should be sent with each request.
/// </summary>
public FluentHttpHeaders? Headers { get; set; }
public FluentHttpHeaders Headers { get; set; } = null!;

/// <summary>
/// Gets or sets the middleware builder.
/// </summary>
public FluentHttpMiddlewareBuilder MiddlewareBuilder { get; set; }
public FluentHttpMiddlewareBuilder MiddlewareBuilder { get; set; } = null!;

/// <summary>
/// Gets or sets handler to customize request on creation. In order to specify defaults as desired, or so.
Expand All @@ -51,7 +51,7 @@ public class FluentHttpClientOptions
/// <summary>
/// Gets or sets formatters to be used for content negotiation, for "Accept" and body media formats. e.g. JSON, XML, etc...
/// </summary>
public MediaTypeFormatterCollection? Formatters { get; set; }
public MediaTypeFormatterCollection Formatters { get; set; } = null!;

/// <summary>
/// Gets or sets the default formatter to be used for content negotiation body format. e.g. JSON, XML, etc...
Expand All @@ -75,7 +75,7 @@ public FormatterOptions()
/// <summary>
/// Configure formatters to be used.
/// </summary>
public MediaTypeFormatterCollection Formatters { get; } = new();
public MediaTypeFormatterCollection Formatters { get; } = [];

/// <summary>
/// Set default formatter to be used when serializing body content and the preferred "Accept".
Expand Down
37 changes: 19 additions & 18 deletions src/FluentlyHttpClient/FluentHttpHeaders.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ namespace FluentlyHttpClient;
/// <summary>
/// <see cref="FluentHttpHeaders"/> options.
/// </summary>
public class FluentHttpHeadersOptions
public record FluentHttpHeadersOptions
{
/// <summary>
/// Predicate function to exclude headers from being hashed in <see cref="FluentHttpHeaders.ToHashString"/>.
Expand Down Expand Up @@ -43,9 +43,9 @@ public partial class FluentHttpHeaders : IFluentHttpHeaderBuilder<FluentHttpHead
{
private static readonly FluentHttpHeadersOptions DefaultOptions = new();
private FluentHttpHeadersOptions _options = DefaultOptions;
private readonly Dictionary<string, string[]> _data = new(StringComparer.OrdinalIgnoreCase);
private readonly Dictionary<string, string[]?> _data = new(StringComparer.OrdinalIgnoreCase);

public string[] this[string key]
public string[]? this[string key]
{
get => _data[key];
set => _data[key] = value;
Expand Down Expand Up @@ -122,7 +122,7 @@ public FluentHttpHeaders(HttpHeaders headers)
/// <param name="value">Header value to add.</param>
public FluentHttpHeaders Add(string header, string value)
{
_data.Add(header, new[] { value });
_data.Add(header, [value]);
return this;
}

Expand Down Expand Up @@ -189,7 +189,7 @@ public FluentHttpHeaders AddRange(IDictionary<string, IEnumerable<string>> heade
public FluentHttpHeaders AddRange(IDictionary<string, string> headers)
{
foreach (var header in headers)
_data.Add(header.Key, new[] { header.Value });
_data.Add(header.Key, [header.Value]);
return this;
}

Expand Down Expand Up @@ -240,7 +240,7 @@ public StringValues Get(string header)
/// <param name="value">Header value to add.</param>
public FluentHttpHeaders Set(string header, string value)
{
this[header] = new[] { value };
this[header] = [value];
return this;
}

Expand Down Expand Up @@ -374,11 +374,12 @@ public string ToHashString()
/// <summary>
/// Converts to dictionary.
/// </summary>
public Dictionary<string, string[]> ToDictionary() => _data;
public Dictionary<string, string[]?> ToDictionary() => _data;

FluentHttpHeaders IFluentHttpHeaderBuilder<FluentHttpHeaders>.WithHeader(string key, string value) => Add(key, value);
FluentHttpHeaders IFluentHttpHeaderBuilder<FluentHttpHeaders>.WithHeader(string key, StringValues values) => Add(key, values);
FluentHttpHeaders IFluentHttpHeaderBuilder<FluentHttpHeaders>.WithHeaders(IDictionary<string, string> headers) => SetRange(headers);
FluentHttpHeaders IFluentHttpHeaderBuilder<FluentHttpHeaders>.WithHeaders(IDictionary<string, string[]> headers) => SetRange(headers);
FluentHttpHeaders IFluentHttpHeaderBuilder<FluentHttpHeaders>.WithHeaders(IDictionary<string, StringValues> headers) => SetRange(headers);
FluentHttpHeaders IFluentHttpHeaderBuilder<FluentHttpHeaders>.WithHeaders(FluentHttpHeaders headers) => SetRange(headers);
}
Expand Down Expand Up @@ -407,43 +408,43 @@ public StringValues AcceptLanguage
/// <summary>
/// Gets or sets the Authorization header.
/// </summary>
public string Authorization
public string? Authorization
{
get => Get(HeaderTypes.Authorization);
set => this[HeaderTypes.Authorization] = new[] { value };
set => this[HeaderTypes.Authorization] = [value];
}

/// <summary>
/// Gets or sets the Cache-Control header.
/// </summary>
public string CacheControl
public string? CacheControl
{
get => Get(HeaderTypes.CacheControl);
set => this[HeaderTypes.CacheControl] = new[] { value };
set => this[HeaderTypes.CacheControl] = [value];
}

/// <summary>
/// Gets or sets the Content-Type header.
/// </summary>
public string ContentType
public string? ContentType
{
get => Get(HeaderTypes.ContentType);
set => this[HeaderTypes.ContentType] = new[] { value };
set => this[HeaderTypes.ContentType] = [value];
}

/// <summary>
/// Gets or sets the User-Agent header.
/// </summary>
public string UserAgent
public string? UserAgent
{
get => Get(HeaderTypes.UserAgent);
set => this[HeaderTypes.UserAgent] = new[] { value };
set => this[HeaderTypes.UserAgent] = [value];
}

/// <summary>
/// Gets or sets the X-Forwarded-For header.
/// </summary>
public StringValues XForwardedFor
public StringValues? XForwardedFor
{
get => Get(HeaderTypes.XForwardedFor);
set => this[HeaderTypes.XForwardedFor] = value;
Expand All @@ -452,9 +453,9 @@ public StringValues XForwardedFor
/// <summary>
/// Gets or sets the X-Forwarded-Host header.
/// </summary>
public string XForwardedHost
public string? XForwardedHost
{
get => Get(HeaderTypes.XForwardedHost);
set => this[HeaderTypes.XForwardedHost] = new[] { value };
set => this[HeaderTypes.XForwardedHost] = [value];
}
}
6 changes: 3 additions & 3 deletions src/FluentlyHttpClient/FluentHttpMessageExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System.Text;
using System.Text;

namespace FluentlyHttpClient;

Expand All @@ -14,12 +14,12 @@ public static class FluentHttpMessageExtensions
public static async Task<FluentHttpResponse> Clone(this FluentHttpResponse response)
{
var contentString = await response.Content.ReadAsStringAsync();
var contentType = response.Content.Headers.ContentType;
var contentType = response.Content.Headers.ContentType!;
var encoding = string.IsNullOrEmpty(contentType.CharSet) ? Encoding.UTF8 : Encoding.GetEncoding(contentType.CharSet);

var cloned = new FluentHttpResponse(new(response.StatusCode)
{
Content = new StringContent(contentString, encoding, contentType.MediaType),
Content = new StringContent(contentString, encoding, contentType.MediaType!),
ReasonPhrase = response.ReasonPhrase,
Version = response.Message.Version,
RequestMessage = response.Message.RequestMessage,
Expand Down
12 changes: 3 additions & 9 deletions src/FluentlyHttpClient/FluentHttpRequest.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace FluentlyHttpClient;
namespace FluentlyHttpClient;

/// <summary>
/// Fluent HTTP request, which wraps the <see cref="HttpRequestMessage"/> and add additional features.
Expand Down Expand Up @@ -30,7 +30,7 @@ public HttpMethod Method
/// <summary>
/// Gets or sets the <see cref="System.Uri"/> for the HTTP request.
/// </summary>
public Uri Uri
public Uri? Uri
{
get => Message.RequestUri;
set => Message.RequestUri = value;
Expand All @@ -42,7 +42,7 @@ public Uri Uri
public HttpRequestHeaders Headers => Message.Headers;

/// <summary>
/// Determine whether has success status otherwise it will throw or not.
/// Determine whether it has success status otherwise it will throw or not.
/// </summary>
public bool HasSuccessStatusOrThrow { get; set; }

Expand All @@ -54,12 +54,6 @@ public Uri Uri
/// <inheritdoc />
public IDictionary<object, object> Items { get; protected set; }

/// <summary>
/// Formatters to be used for content negotiation for "Accept" and also sending formats. e.g. (JSON, XML)
/// </summary>
[Obsolete("This was added to be passed down to the middleware. Instead in middleware use FluentHttpMiddlewareClientContext.Formatters.")]
public MediaTypeFormatterCollection? Formatters { get; set; } // deprecated: remove

/// <summary>
/// Initializes a new instance.
/// </summary>
Expand Down
Loading

0 comments on commit 3a5764f

Please sign in to comment.