-
Notifications
You must be signed in to change notification settings - Fork 502
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
exp/clients/horizon: add prev and next methods for Ledger Requests #1132
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From the options you listed I think we should go with number 2. I think we can easily solve passing interface{}
by creating a Page
interface like:
type Page interface {
getNextPageURL() (string, error)
getPrevPageURL() (string, error)
}
Then we just need to implement it on page structs. The example code would be something like:
page, _ := client.Ledgers(LedgerRequest{Order: OrderDesc, Limit: 200})
nextPage, err := client.NextPage(page)
The problem is that users would need to do a type checking (as NextPage
returns Page
) but it will prevent a lot of code duplication (Next
, Prev
methods on each page struct).
// sendURLRequests sends a request to horizon when a url is provided. | ||
func (c *Client) sendURLRequest(rURL string, a interface{}) (err error) { | ||
_, err = url.Parse(rURL) | ||
if err != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Client.sendRequest
should really use this method internally.
} | ||
|
||
err = decodeResponse(resp, &a) | ||
cancel() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Better to use defer cancel()
instead of two cancel()
s.
Thanks for your suggestion @bartekn the only reservation I have is the type checking for users. But I guess if we balance duplication with usability. If there are no objections, we can implement this. @ire-and-curses @tomquisel ? |
Since this is an SDK, I feel like we should do as much as possible to make it simple for users. I think it's pretty annoying to have to do the type check (user needs to know what type they are expecting, which requires looking at docs). I'd like to hear if there's any issues with the other idea we discussed internally:
If this is viable, then you could implement something that looks more like the JS approach. Having that similarity is valuable IMHO. Overall I don't think creating a bunch of next methods is really too bad. Especially if you could abstract any of it to a helper. |
I agree that type checking can be a bit of a drag, but the user really doesn't need to guess because they will be calling Thanks for bringing up this other idea, I had forgot about this. Yes, I agree this is the closest implementation to the JS SDK. One drawback here is that we might need to use a new http client to fulfil the requests or always pass the current horizon client as an parameter to the |
Both solutions are interesting but I think type EffectsPage struct {
Page horizonProtocol.EffectsPage
}
func (*p EffectsPage) Next(client *Client) (EffectsPage, error) {
...
} But then devs would need to access page data like: There's also something we can do to prevent using type checks in my initial proposal. We can create page, _ := client.Ledgers(LedgerRequest{Order: OrderDesc, Limit: 200})
nextPage, err := client.NextLedgersPage(page) Users still need to remember that they're using a specific page type but in case of mistake it would be caught at compilation time. |
Hey @bartekn thanks for looking into this a bit more. I like the idea of creating |
This PR adds support for the horizonclient to be able to return previous and next result pages for certain endpoints; similar to the JS sdk
result.next()
.Here, it is implemented for
/ledgers
. For each page returned, you can callLedgerRequest.Next(returnedPage, client)
to get the next set of pages from theLink
specified in thereturnedPage
. This can also the be done to get previous page.I would like to know your thoughts around having
Prev()
andNext()
on theLedgerRequest
struct.Before settling to implement it in this manner I had some other options
Implement
Prev()
andNext()
on the result struct, e.ghProtocol.LedgersPage.Next()
. This would mean that I will have to use a new client to fulfil the requests. Using the same horizon client will lead to a cyclic dependency error.Implement
Prev()
andNext()
on the horizon client, e.gClient.Next(resultPage) resultPage
. Theproblem with this is that
resultPage
will have to be of typeinterface{}
in other to be used by all the different result structs.