typesense / typesense-go

Go client for Typesense: https://github.com/typesense/typesense
Apache License 2.0
208 stars 55 forks source link

Add support for generics #144

Open Hades32 opened 1 year ago

Hades32 commented 1 year ago

Search results are untyped (map[string]any) which makes this very unergonomic to use

Currently we're working around it with a custom search method

func searchCollection[TDoc any](ctx context.Context, collection string, params *api.SearchCollectionParams) (*Result[TDoc], error) {
    resp, err := typesenseApiClient.SearchCollection(ctx, collection, params)
    if err != nil {
        return nil, err
    }
    defer resp.Body.Close()
    if resp.StatusCode > 299 {
        return nil, utils.ErrHighStatusCode
    }
    var results Result[TDoc]
    err = json.NewDecoder(resp.Body).Decode(&results)
    if err != nil {
        return nil, err
    }
    return &results, nil
}

and matching types

type  Result[TDoc any] struct {
    GroupedHits []GroupedHit[TDoc] `json:"grouped_hits,omitempty"`
    Hits []*ResultHit[TDoc] `json:"hits,omitempty"`
...
tadejsv commented 10 months ago

@Hades32 The way you are doing it is the only way possible, it wouldn't be possible to use generics using the methods from this library (for example something like client.Collection("companies").Documents().Search[Company](searchParameters)), because Go does not allow parametrized methods.

The only way would be to set the result type at client creation, but then that client is effectively bound to one index only. Or well, provide a convenience function like you did.

Another way would be to allow you to provide a pointer to the result struct that you want to unmarshall the result into - the signature for that argument in the Search function would simply be interface{}, so this wouldn't even require generics.

kishorenc commented 10 months ago

Happy to accept a PR with any helper / utility functions that help with usability.