Skip to content

Feature proposal: WithRoundTripMiddlewares and WithSharedRoundTripMiddleware #150

@pseudo-su

Description

@pseudo-su

Background

The problem I'm currently facing is that I have the requirement to implement an API client with the ability to have the following features:

  • shared Correlation ID middleware across all operations
  • shared Tracing middleware (using opentracing /opentracing-go)
  • Resiliency features (middleware) configured per operation (retry/backoff/circuitbreaker) EG: one endpoint might need to have retry+backoff+circuitbreakers configured but a different endpoint might not allow any kind of retry.

I would like to continue using the client generated by oapi-codegen however with the two ClientOptions currently available to help (WithHttpClient and WithRequestEditorFn) I'm not able to achieve the following two things:

  • Configure a middleware that operates on the request and response for all operations (the RequestEditorFn only allows you to edit the request before it's sent)
  • Configure a middleware for only a specific endpoint.

I originally commented on this issue: #87 (comment)

Proposed solution

I've opened up a PR where I've manually created an example of what the output of the code generation could be changed to in order to support my use-cases. #149

PR #156

Main changes:

  • Define RoundTripMiddleware as a function that takes in a Do function and returns a new Do function
  • Each operation Would have it's own DoFn created by wrapping the client.Client.Do in the shared middleware and/or middleware specific to that operation
  • RequestEditorFn doesn't have to be a special case /override that appears in every operation function because it's applied as a middleware when the *Client is created

I'd like to gather feedback on if this is a welcome change as I start to investigating the oapi-codegen client generation implementation to support the change.

Notes

  • I made the choice to call it RoundTripMiddleware because it mirrors the http.RoundTripper interface https://golang.org/pkg/net/http/#RoundTripper. Another name I found in a different package for a similar thing is Tripperware https://github.com/improbable-eng/go-httpwares#tripperware-client-side
  • I've actually made the new implementation of WithRequestEditorFn a middleware (keeping it as an option you can pass for compatibility reasons). I think this is a good example of how RoundTripMiddleware allows more flexibility to support whatever use-case might be required. Technically you could probably remove RequestEditorFn and support all the required use-cases with the shared WithSharedRoundTripMiddleware option instead (but I presume backwards compatibility would mean that we'd keep the option).

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