Skip to content

How to use BrowseObjects with v4 #772

@greg0ire

Description

@greg0ire

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions