Skip to content
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

Add interface to EvaluationClient (Go) #700

Closed
markphelps opened this issue Feb 7, 2025 · 2 comments
Closed

Add interface to EvaluationClient (Go) #700

markphelps opened this issue Feb 7, 2025 · 2 comments

Comments

@markphelps
Copy link
Contributor

Discussed in https://github.com/orgs/flipt-io/discussions/3886

Originally posted by zeryel February 7, 2025
Greetings. I want to start using Flipt, and I noticed that current SDK (Go) haven't interface for EvaluationClient - which makes it very difficult to write unit tests.
I suggest implementing the EvaluationClient's interface in SDK, i.e.:

type (
	// ClientInterface describes methods of EvaluationClient
	ClientInterface interface {
		EvaluateVariant(ctx context.Context, flagKey, entityID string, evalContext map[string]string) (*VariantEvaluationResponse, error)
		EvaluateBoolean(ctx context.Context, flagKey, entityID string, evalContext map[string]string) (*BooleanEvaluationResponse, error)
		EvaluateBatch(ctx context.Context, requests []*EvaluationRequest) (*BatchEvaluationResponse, error)
		ListFlags(ctx context.Context) ([]Flag, error)
		Close() error
	}

	// EvaluationClient wraps the functionality of making variant and boolean evaluation of Flipt feature flags.
	EvaluationClient struct {
		engine         unsafe.Pointer
		namespace      string
		url            string
		authentication any
		ref            string
		updateInterval int
		fetchMode      FetchMode
	}
)

// NewEvaluationClient constructs a Client.
func NewEvaluationClient(opts ...clientOption) (ClientInterface, error) {
    client := &EvaluationClient{
	namespace: "default",
    }
    ...
    return client, nil
}
```</div>
@markphelps markphelps transferred this issue from flipt-io/flipt Feb 7, 2025
@GeorgeMac
Copy link
Member

I'm sure there exist Go client libraries that expose a matching interface out there. So take what I am saying next here with a grain of salt, it has a heavy dose of personal preference. If doing this saves people time and doesn't paint any other endeavours into a corner, then I say go for it!

That said, I can't think of many clients publishing a large interface that is identical to the struct that implements it.
I personally think large exported interfaces have diminishing returns.
Interfaces are useful because they allow a consumer to define the minimum subset they need to solve their problem.
Usually, I imagine most call sites probably only need one of the eval methods. They're less concerned with e.g. listing flags (unless you're doing a batch of all flags), or closing the client as that is usually a parents responsibility which passes the client to it in the first place. Depending on the larger interface, means there is a bunch of unused methods that need to be mocked that will likely never be called.

Moreover, depending on an external interface tied to an entire clients surface area, means that as that surface grows, so must the rest of the implementations.
Which means any generated mocks, or worse, hand written mocks will have to be updated before dependent code compiles again. Even though none of their code actually depends on these new methods.

What I describe here (more smaller interface) does lead to a bit of a proliferation of smaller mocks / spies / mimics everywhere and is less DRY.
So if its pragmatic and saves people time to expose something like this then great!
Also, folks are always welcome to define subsets for themselves to avoid what I described above (and ignore the pre-defined interface altogether to avoid potential compilation errors on fututre updates).

@erka
Copy link
Collaborator

erka commented Feb 7, 2025

I support @GeorgeMac words. I think the aws-sdk-go is the great example of that vision. v1 provided the interfaces for the AWS services but v2 doesn't provide them anymore. You just define the minimal internal interface for AWS service with methods you care about. Your tests are very stable with external changes.

@markphelps markphelps closed this as not planned Won't fix, can't repro, duplicate, stale Feb 8, 2025
@github-project-automation github-project-automation bot moved this to Done in Roadmap Feb 8, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: Done
Development

No branches or pull requests

3 participants