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).
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:
opentracing /opentracing-go)I would like to continue using the client generated by
oapi-codegenhowever with the twoClientOptions currently available to help (WithHttpClientandWithRequestEditorFn) I'm not able to achieve the following two things:RequestEditorFnonly allows you to edit the request before it's sent)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. #149PR #156
Main changes:
RoundTripMiddlewareas a function that takes in aDofunction and returns a newDofunctionDoFncreated by wrapping theclient.Client.Doin the shared middleware and/or middleware specific to that operation*Clientis createdI'd like to gather feedback on if this is a welcome change as I start to investigating the
oapi-codegenclient generation implementation to support the change.Notes
RoundTripMiddlewarebecause it mirrors thehttp.RoundTripperinterface https://golang.org/pkg/net/http/#RoundTripper. Another name I found in a different package for a similar thing isTripperwarehttps://github.com/improbable-eng/go-httpwares#tripperware-client-sideWithRequestEditorFna middleware (keeping it as an option you can pass for compatibility reasons). I think this is a good example of howRoundTripMiddlewareallows more flexibility to support whatever use-case might be required. Technically you could probably removeRequestEditorFnand support all the required use-cases with the sharedWithSharedRoundTripMiddlewareoption instead (but I presume backwards compatibility would mean that we'd keep the option).