0

I'm new to Go and I'm working on a little project that basically wraps an API in a kubectl style cli (myapp get <resource> etc). I'm using an existing package to interact with the API since I'm trying to keep the footprint of the project fairly small and being new I'm happy to be able to delegate out some of the logic.

To list each resource I have a function that handles the paginated response from the API and for any given type of resource this code is essentially identical apart from the types involved. Ideally I want to put this code into a single function which can be called for any resource type.

So my question is for my example code below is there a way to implement a listAnything() function that can be called (with relevant parameters) to list either X or Y (or any other similar resource). I feel like this should be possible but maybe the fact I'm using so many types from the client package means it isn't.

I've tried to include all the relevant code but for context this is the package I'm using github.com/hashicorp/go-tfe

My code

import p "someApiClient"

type Client struct {
    Client  p.Client
    id      string
}

func listX(ctx context.Context, client *Client, options *p.XListOptions) []*p.X {
    w, err := client.Client.X.List(ctx, client.id, options)
    if err != nil {
        log.Fatal(err)
    }
    X := w.Items
    for currentPage := 2; w.Pagination.NextPage != 0; currentPage++ {
        options.ListOptions = p.ListOptions{PageNumber: currentPage}
        w, err = client.Client.X.List(ctx, client.id, options)
        if err != nil {
            log.Fatal(err)
        }
        X = append(X, w.Items...)
    }
    return X
}

Code in someApiClient

type Xs interface {
    List(ctx context.Context, id string, opt XListOptions) []*X
    // other X specific API calls
}

type xs struct {
    client Client
}

func (xs) List(ctx context.Context, id string, opt XListOptions) []*X {...}

type XListOptions struct {
    ListOptions
    foo         string
}

type Ys interface {
    List(ctx context.Context, id string, opt YListOptions) []*Y
    // Other Y specific API calls
}

type ys struct {
    client Client
}

func (ys) List(ctx context.Context, id string, opt YListOptions) []*Y {...}

type YListOptions struct {
    ListOptions
    bar         string
}

type ListOptions struct {
    PageNumber  int
}

Thanks for taking the time to help a Go newcomer!

0 Answers0