-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
[RFC] HttpClientAdapter and Octokit - Future Plans #781
Comments
This is on my list, but it will take me some time to really think it through. Corner me at BUILD. 😄 🍸 |
Word 🍸 |
(passing by) Just encountered with support of repository redirects. Forced to checkout sources and "invent crutch" there making IRequest mutable in part of endpoint. |
Let's discuss your workaround in a different thread to this. It's on my roadmap, I'm just trying to figure out the best way to get there right now... |
Regarding the redirect issue, I've been using this https://gist.github.com/darrelmiller/a3baeb6976acd9f23243 in one of my client applications to replace the autoredirect done by HttpWebRequest. It could use some love, but it might be an ok starting point. |
@shiftkey Take a look at this and let me know what you think darrelmiller@e5d7d6e I'm having trouble getting the tests to run at the moment, so it isn't tested. Just consider it an idea. I optionally allow passing in a HttpMessageHandler into HttpClientAdapter. I store a HttpClient instance as a field and reuse it. In order to allow auto redirects to be turned on and off, I use the HttpRequestMessage.Properties collection to relay the setting to the new redirect message handler. |
Update: aiming to land repository redirects over in #808 as a way to figure out the |
With #808 almost ready to go out the door, I found myself with a quiet moment to reflect on how to improve the initialization of I'd like to simplify this down to a number of options which are set by the user (this is just a demo): var options = new ClientOptions
{
AppName = "my-cool-app",
Credentials = new Credentials("my-token"),
Server = "https://enterprise.my-work.com",
UseDefaultProxy = true
}; And as these are all HTTP-specific, they could be transformed into a var handler = OctokitMessageHandlerFactory.Create(options);
var client = new GitHubClient(handler); This could also be the extensibility hook for doing more flexibile things at the HTTP level: var handler = OctokitMessageHandlerFactory.Create(options);
var cachingHandler = new CachingMessageHandler { InnerHandler = handler };
var client = new GitHubClient(cachingHandler); I need to think a bunch about how to transition things carefully, but the wheels are already turning... |
I like the fact that your proposed GitHubClient extensibility model mirrors the standard HttpClient model. It hides all the IHttpClient, IConnection, HttpClientAdapter stuff from someone who just wants to plug in an extra piece of middleware. |
That's something I've had in mind for a while (@haacked jump in here if you disagree with this direction) and ultimately we're re-implementing a bunch of the middleware currently - and I'd just love to get out of the way of those who want to dive in. The |
May I jump in here if I don't disagree? ✨ |
I like the I do think we should retain the simpler |
You want to port the existing |
Seeing how we're all roughly on the same page here, I'm going to open up a new issue to track the roadmap and break down the work better. |
Not necessarily. I just mean I want to retain some of the existing |
@haacked okay, I'll keep that in mind |
The Setup
You've probably never looked at
HttpClientAdapter
before. That's because it's buried deep inside Octokit. But that's not been a deliberate thing - it's just the central place for actually doing the leg work of creating, sending and receiving HTTP requests.If you wanted to create it by hand in Octokit today, this is the code you need:
But anyway, let me start with a few notes:
Repository Redirects is currently being tested in the GitHub API - I'd love to support this but it's currently not possible without reworking🚢edHttpClientAdapter
.The Confrontation
As there's many intertwined concepts in here, I'm gonna try and just start from the beginning:
HttpClient and You
Initially we used
HttpClientAdapter
to abstract away all theHttpClient
-ness. And that's fine. ButIHttpClient
is just one method (very similar toHttpClientAdapter
), it has it's own abstraction forIRequest/IResponse
and the conversion toHttpRequestMessage/HttpResponseMessage
isa closely guarded secretjust kept internal.If we extract the message building logic out of
HttpClientAdapter
you're just left with the simple wrapper overHttpClient
. And that's okay, maybe we don't need to 🔥 it off right away. But I think that's some low-hanging fruit to do to appease the SRP gods.Use
HttpClientHandler
RightThe other thing that
HttpClientAdapter
handles is the setup ofHttpClient
. In hindsight, there is a better place for much of this code - a custom implementation ofHttpClientHandler
! This could be passed in as actor
parameter, removing yet another responsibility ofHttpClientAdapter
.There's one issue I have with this approach, and it's the global
Timeout
property onHttpClient
- there doesn't seem to be an equivalent at the handler level. I dislike leaning on this crutch but it's been useful when uploading releases, so I'm cautious about migrating away from this.A thought I had was to combine the received cancellation token with a timeout-based cancellation token, like this:
I'm not even sure this will work, but I'm keen to try it out as it takes away one of my major pain points with
HttpClient
as-is.Pluggable
HttpClientHandler
For AllAnd now we get into the fun stuff. For a side-project I wanted to implement a caching version of
HttpClientHandler
to store responses on-disk for a period of time.This is approximately what the code for that handler would look like:
Note: I bet
HttpResponseMessage
isn't serializable and this is all just going to end in tears. But again, I can test this out first.Note: as @paulcbetts asked me about over Twitter, I think
HttpClientAdapter
could depend onHttpMessageHandler
- but the defaults would be built offHttpClientHandler
particularly to getGZip
/Deflate
compression wherever possible.We currently have a lot of overloads on
GitHubClient
ctors
, and I'd like to review whether we can add deprecated in favour of scenarios like this.CredentialsCache And You
Lastly, there's how credentials work.
I've included discussions around credentials here because this is another area that
HttpClientHandler
does well - so perhaps we can deprecate our code for managing credentials and just defer to whatever is in the handler. I'm kinda undecided on this, but our current setup is limited in two significant scenarios:The general advice here seems to be to use
System.Net.AuthenticationManager
from this process because this only seems to exist on .NET 4.5. I've got an alternative way to do this which covers all platforms, but feels primitive.As an end-user, I really don't want you to care about setting these things up - so how does this feel as a hypothetical API?
By making this more configurable, you can use
HttpClientAdapter
directly for making requests to generic HTTP resources (like images) but without being able to control authentication better, you're at the mercy of hoping resources do not require authorizationA Potential Roadmap
So let's say this is considered a thing worth investing in. How can we break up this big task into multiple, manageable tasks:
Drop the dependency onHttpClient.Timeout
Prove that you can use aCancellationToken
with a timeout instead.Swap out the internal behaviour to remove the dependencyNo longer createHttpClient
per-request 🔪 🎉 💃This was completed in #796 and will ship in v0.11
Change HttpClientAdapter to take in a
HttpMessageHandler
ctor
dependencyImplement redirect handling (with correct authentication handling)
HttpMessageHandler
implementation to support processing redirectsWhen we get to here, we have made the work required to extract the mapping unnecessary (because you don't need to plug in there any more) however the credentials work remains unclear.
cc @haacked when you get a moment to unwind over a nice Manhattan
cc @darrelmiller and @akoeplinger for API and
HttpClient
feelscc @forki @distantcam @thedillonb for end-user feedback
The text was updated successfully, but these errors were encountered: