-
Notifications
You must be signed in to change notification settings - Fork 63
Description
It's not the first time I'm encountering this issue, but today, I thought I'd report it before the consequences spread in my project too much.
So how do you browse for records with v4? I think the best practice is to use this high-level helper. Otherwise, you'd be doing plumbing with the API using client.Browse()
The docs say:
This helper function iterates over the paginated API response from the Browse API operation and lets you run an aggregator function on every iteration.
Documentation issue
The first issue is a documentation issue: how do you pass the aggregator function?
👉 you have to pass it using opts
, and the option you pass can be search.WithAggregator
, as indicated here:
Use the `WithAggregator` option to collect all the responses. |
First DX issue
The second issue is a DX issue: the signature of the function you pass to search.WithAggregator
is func(any, error)
:
func WithAggregator(aggregator func(any, error)) iterableOption { |
There is no guarantee about the response you are going to get. I would have expected func(*search.BrowseResponse, error)
instead.
I believe that's because the WithAggregator
helper can be used with more than just BrowseObjects
, which makes sense.
To work this around, I've been forced to write my own helper, it goes like this:
package algoliahelpers
import (
"fmt"
"github.com/algolia/algoliasearch-client-go/v4/algolia/search"
)
type aggregator func(response *search.BrowseResponse)
func WrapAggregator(
aggregatorFunc aggregator,
) func(response any, errorResponse error) {
return func(response any, errorResponse error) {
if errorResponse != nil {
panic(errorResponse)
}
res, ok := response.(*search.BrowseResponse)
if !ok {
panic(fmt.Errorf("%w, got %T", ErrUnexpectedResponseType, response))
}
aggregatorFunc(res)
}
}
I have yet to figure out how to avoid these calls to panic
Second issue
Even with that first DX issue addressed, another big DX issue remains: in v3, using browse meant you could obtain an iterator and not think about responses: they were completely abstracted. Now, the abstraction leaks, and to use this, you have to deal with responses, when before you dealt with hits directly. This feels like a big regression, to be honest.
Third issue
As you can see above, there is not much room for simple error handing. It would have been nice to be able to return an error
from the aggregator, causing the program to halt cleanly in case of error.