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

Reactive Milestone Client #138

Merged
merged 8 commits into from
Nov 1, 2013
Merged

Conversation

dahlbyk
Copy link
Contributor

@dahlbyk dahlbyk commented Oct 31, 2013

Using optional parameters in 5baaa17 seems cool since it's internal only.

@dahlbyk
Copy link
Contributor Author

dahlbyk commented Oct 31, 2013

Prereq for #126

@@ -7,9 +7,9 @@ namespace Octokit.Reactive.Internal
{
internal static class ConnectionExtensions
{
public static IObservable<T> GetAndFlattenAllPages<T>(this IConnection connection, Uri url)
public static IObservable<T> GetAndFlattenAllPages<T>(this IConnection connection, Uri url, IDictionary<string, string> parameters = null, string accepts = null)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure the parameters is needed. The nextPageUrl is returned as part of the previous page's response in the Link header. I would assume it would be a fully formed URL for retrieving the next page of results. See the pagination docs for the GitHub API for more details. Were you finding that this was not the case?

The accepts parameter, on the other hand, makes total sense!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me take a closer look at this - I'm pretty sure we need parameters for the initial call but you're probably right that it's redundant for successive calls. Assuming that's the case, how does this look?

         public static IObservable<T> GetAndFlattenAllPages<T>(this IConnection connection, Uri url, IDictionary<string, string> parameters = null, string accepts = null)
         {
-            return GetPages(url, nextPageUrl => connection.GetAsync<List<T>>(nextPageUrl, parameters, accepts).ToObservable());
+            return GetPages(url, parameters, (pageUrl, pageParams) => connection.GetAsync<List<T>>(pageUrl, pageParams, accepts).ToObservable());
         }

-        static IObservable<T> GetPages<T>(Uri uri,
-            Func<Uri, IObservable<IResponse<List<T>>>> getPageFunc)
+        static IObservable<T> GetPages<T>(Uri uri, IDictionary<string, string> parameters,
+            Func<Uri, IDictionary<string, string>, IObservable<IResponse<List<T>>>> getPageFunc)
         {
-            return getPageFunc(uri).Expand(resp =>
+            return getPageFunc(uri, parameters).Expand(resp =>
             {
                 var nextPageUrl = resp.ApiInfo.GetNextPageUrl();
                 return nextPageUrl == null
                     ? Observable.Empty<IResponse<List<T>>>()
-                    : Observable.Defer(() => getPageFunc(nextPageUrl));
+                    : Observable.Defer(() => getPageFunc(nextPageUrl, null));
             })
             .Where(resp => resp != null)
             .SelectMany(resp => resp.BodyAsObject);

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, don't we already apply the parameters to the URL before we call this? If we do that, we never need to worry about it here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is our only chance to apply parameters - without passing them in here, they're not respected. I don't suppose you or your colleagues know of a public repo with more than a page worth of Milestones for testing purposes? At least for the first page, this does correctly apply parameters.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is our only chance to apply parameters - without passing them in here, they're not respected.

Ah right. Why'd you remove the accepts parameter? That seems like it should be necessary if we need to pass something other than the default. Or do we not need to do that here?

know of a public repo with more than a page worth of Milestones for testing purposes?

I don't offhand. I suppose we could create one. We could have the integration test create one. By default, it's 30 a page.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah right. Why'd you remove the accepts parameter? That seems like it should be necessary if we need to pass something other than the default. Or do we not need to do that here?

MilestonesClient doesn't pass accepts, so I'm not either. I believe it's still correctly wired up in GetAndFlattenAllPages though.

@haacked
Copy link
Contributor

haacked commented Oct 31, 2013

Thanks a lot for submitting this! I had one comment on something that looks incorrect to me.

Also, would love to see some unit tests (or at the very least, an integration test).

@dahlbyk
Copy link
Contributor Author

dahlbyk commented Nov 1, 2013

Now with ∞ more tests, though no integration test that exercises paging.

haacked added a commit that referenced this pull request Nov 1, 2013
@haacked haacked merged commit bc82697 into octokit:master Nov 1, 2013
@haacked
Copy link
Contributor

haacked commented Nov 1, 2013

Thanks!
applause-joker

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.

2 participants