Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v2.0.0 release #7

Merged
merged 37 commits into from
Jan 24, 2024
Merged

v2.0.0 release #7

merged 37 commits into from
Jan 24, 2024

Conversation

matteocontrini
Copy link
Owner

@matteocontrini matteocontrini commented Oct 28, 2023

Draft of release notes:

Changes

  • Target framework updated to .NET 6.0 (b0eaebf)
  • Enabled nullable types (bf727f7)
  • Upgraded Flurl dependency (URL builder) to v4 (6098e03, d7d2a27)
  • New EnsureSuccessStatusCode method on the response (5f1c96b)
  • New StatusCode property on the response (4503c87)
  • IHttpClientFactory.GetProxiedClient() now has the request URI parameter too (06677e9)
  • New extensible payload serialization: introduced JsonPayload, XmlPayload, FormUrlEncodedPayload, PlainTextPayload and removed the ContentType property (924b708, 7548e3c)
  • Changed how responses can be read: removed ReadBody, DownloadFileName, ResponseEncoding properties from the request and added new Read* methods to the response
  • The default HttpClientFactory can now be customized without replacing it (bbb7cbb, 6a960d3)
  • The default constructor of HttpRequest was removed
  • The default value for the Timeout property on the request was changed from TimeSpan.Zero to System.Threading.Timeout.InfiniteTimeSpan (9fa8d4c)
  • Exceptions now expose the request, response and elapsed time as properties (c4023db)

Upgrading from v1.x

Response reading and deserialization changes

If you used the Body property on the response, you should now use one of these methods to obtain the response:

  • Task<Stream> ReadStream()
  • Task<string> ReadString()
  • Task<string> ReadString(Encoding encoding)
  • Task<T?> ReadJson<T>(JsonSerializerOptions? options = null)
  • Task<string> DownloadFile(string path)
  • Task<T?> ReadXml<T>(XmlReaderSettings? settings = null)
  • Task<byte[]> ReadBytes()

All these methods except for ReadStream take into account the request timeout.

The updated README covers these methods, their usage and their pitfalls in greater detail.

Request serialization changes

If you used the request serialization feature, you should remove the ContentType property from requests and instead set the Payload with an instance of any class implementing the IPayload interface. Pass your payload to the constructor of these classes.

The library provides implementations for the following payload types:

  • JsonPayload (based on System.Text.Json)
  • XmlPayload (now with UTF-8 encoding instead of UTF-16)
  • FormUrlEncodedPayload
  • PlainTextPayload

With more likely coming in the future.

The updated README contains instructions on how to extend this mechanism and create new payload types.

Custom HttpClientFactorys

If you implemented your own IHttpClientFactory and/or inherited from HttpClientFactory, you must change the signature of the GetProxiedClient method as follows:

public HttpClient GetProxiedClient(Uri requestUri, Uri proxyUri)

Also, the default factory now allows for some basic customizations which weren't possible before without swapping the factory implementation. The updated README covers these new options in detail, which might remove the need for replacing the factory implementation altogether.

Default Timeout

If you relied on the fact that the default value of Timeout on HttpRequest was TimeSpan.Zero, the new default is System.Threading.Timeout.InfiniteTimeSpan (as it should always have been).

@matteocontrini matteocontrini marked this pull request as draft October 28, 2023 16:50
@snake-4
Copy link

snake-4 commented Nov 10, 2023

Looks great! Though most of these are the changes that I tried to get merged 3 years ago 😆

@matteocontrini
Copy link
Owner Author

@snake-4 do you mean PR #5? Most of those things (4 out of 7) were actually released last year 🙂. For the remaining ones:

  • Instead of renaming the enum for request serialization, which would have been a breaking change anyway, I decided to follow a different approach altogether, which I think is more extensible and customizable
  • I also decided not to change the Proxy property to IWebProxy, at least for now, since SOCKS support is now built into .NET and I don't see other use cases. I'd like not to lose the convenience of passing a proxy URI with credentials (which are automatically parsed from the URI by the library)
  • Still thinking about automatic client disposal and how to do it right

The focus of 2.0 is the new serialization and deserialization system, along with better documentation on how to use it correctly, especially with HttpCompletionOption.ResponseHeadersRead. I think that in that situation this library now handles things better than other libraries or the HttpClient itself, for example by taking into consideration the timeout automatically and transparently, something that you otherwise would need to do by yourself.

Thanks for the feedback!

@snake-4
Copy link

snake-4 commented Nov 12, 2023

@snake-4 do you mean PR #5? Most of those things (4 out of 7) were actually released last year 🙂. For the remaining ones:

  • Instead of renaming the enum for request serialization, which would have been a breaking change anyway, I decided to follow a different approach altogether, which I think is more extensible and customizable
  • I also decided not to change the Proxy property to IWebProxy, at least for now, since SOCKS support is now built into .NET and I don't see other use cases. I'd like not to lose the convenience of passing a proxy URI with credentials (which are automatically parsed from the URI by the library)
  • Still thinking about automatic client disposal and how to do it right

The focus of 2.0 is the new serialization and deserialization system, along with better documentation on how to use it correctly, especially with HttpCompletionOption.ResponseHeadersRead. I think that in that situation this library now handles things better than other libraries or the HttpClient itself, for example by taking into consideration the timeout automatically and transparently, something that you otherwise would need to do by yourself.

Thanks for the feedback!

I had implemented client disposal by discarding least recently used HttpClient and also by keeping track of last access timestamps for them.

@matteocontrini matteocontrini marked this pull request as ready for review January 24, 2024 17:12
@matteocontrini matteocontrini merged commit c0b8b90 into main Jan 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants