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

Chain Chi middlewares in reverse order so they execute first-to-last #787

Merged
merged 6 commits into from Oct 22, 2022

Conversation

ericvolp12
Copy link
Contributor

@ericvolp12 ericvolp12 commented Oct 14, 2022

Resolves reversed-ordering of Chi middleware chaining.

After this change, Chi middlewares will be applied in first-to-last ordering i.e. earlier wired/invoked middlewares will run before later wired middlewares.

This addresses #687 and #786

Not sure how I'd go about testing this since the existing unit tests don't seem to have complex middlewares, could use some advice if we want to include a unit test for this.

Note that this will change behavior for Chi users who wired their middlewares in reverse order to compensate, I think most people at this point have adopted version pinning for code generation since we've had some breaking changes in the past few versions but it's worth noting in the release notes.

@ericvolp12
Copy link
Contributor Author

Oh, I just realized these issues were already addressed in #688 but it didn't end up being followed-up on.

Copy link
Collaborator

@jamietanna jamietanna left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey, thanks for this - I think we'll need to make this an opt-in configurable change, rather than a breaking change.

The breaking change I think you're referring to is when we changed the change to how to invoke the generator?

Although, yes, we could've rolled that out in a less breaking fashion, I think that's more noticeable as a breaking change to us subtly changing underlying behaviour, which may not be clear to consumers, and break a lot of applications.

@ericvolp12
Copy link
Contributor Author

I was more referencing this rollback release after we broke the type signature of some of the generated code for Gin - https://github.com/deepmap/oapi-codegen/releases/tag/v1.8.1

I'll look into turning this into a configuration-driven change though it might be a few days before I can get around to it.

@ericvolp12
Copy link
Contributor Author

ericvolp12 commented Oct 15, 2022

Okay JK I got bored and decided to work on this.

The changes as shown now pass a new TemplateParameters object into the template engine which include an Operations property that is the old ops object that used to be the root of most templates (a []OperationDefinition) as well as an Options property which is just the whole Configuration object.

This allows us to use Configuration values inside the template to conditionally render the template in different ways.

In this case, all I've done is gated the new mechanism for Chi middleware chaining behind the new Compatibility configuration variable Options.Compatibility.ApplyChiMiddlewareFirstToLast.

{{if $.Options.Compatibility.ApplyChiMiddlewareFirstToLast}}
for i := len(siw.HandlerMiddlewares) -1; i >= 0; i-- {
  handler = siw.HandlerMiddlewares[i](handler)
}
{{else}}
for _, middleware := range siw.HandlerMiddlewares {
  handler = middleware(handler)
}
{{end}}

To start, we can have this be an opt-in compatibility option but using this new method of template rendering, it should be trivial to make the first-to-last chaining order an opt-out when we decide enough time has passed to establish it as the default.

This will also open up the ability to have template-specific feature flags in configuration that don't require maintaining lots of additional templates but just feature Option gating logic inside the templates instead.

This change required subtly updating most of the template files to index into the .Operations field of the Template Parameters at the top-level range statements but the end result is strictly the desired change to the Chi template when the compatibility option is selected so there should be no breakage or backward incompatibility without an explicit opt-in from Chi users.

@deepmap-marcinr
Copy link
Contributor

That's a lot of work you did, but options are globally stored on globalstate.options, precisely because it's a pain to pass them around everywhere, so your change can be done without all the changes to all the templates. All you really need to change is that one chi template and pass it an additional flag in its context, rather than changing all of them.

@ericvolp12
Copy link
Contributor Author

That's a lot of work you did, but options are globally stored on globalstate.options, precisely because it's a pain to pass them around everywhere, so your change can be done without all the changes to all the templates. All you really need to change is that one chi template and pass it an additional flag in its context, rather than changing all of them.

Okay, I didn't see that getting injected as a Template Func, thanks for the pointer!

In other news, I learned what Go Template Funcs are today!

Hopefully this change is a lot simpler and makes more sense, the activation functionality is the same but we're eschewing all my previous changes that were injecting options a second time.

@ericvolp12
Copy link
Contributor Author

I saw this line while Go Generating locally:

go generate ./...
go: downloading github.com/matryer/moq v0.2.7

Looks like something got updated that the CI is unhappy with there?

@deepmap-marcinr
Copy link
Contributor

It looks like a dependency got updated, it's no big deal, you just haven't fetched it before.

@ericvolp12
Copy link
Contributor Author

It looks like a dependency got updated, it's no big deal, you just haven't fetched it before.

Does this look okay to merge now or is there anything else you'd like me to change?

@deepmap-marcinr deepmap-marcinr merged commit eea15c7 into deepmap:master Oct 22, 2022
@deepmap-marcinr
Copy link
Contributor

deepmap-marcinr commented Oct 22, 2022 via email

@ericvolp12 ericvolp12 deleted the chi_middleware_ordering branch October 22, 2022 19:14
adrianpk pushed a commit to foorester/oapi-codegen that referenced this pull request Jan 16, 2024
…eepmap#787)

* Chain Chi middlewares in reverse order so they execute first-to-last

* Add updated generated files for Chi tests

* Pass Configuration Options into Templates to allow for conditional rendering

* Revert "Pass Configuration Options into Templates to allow for conditional rendering"

This reverts commit 34f1162.

* Use existing template Func to access options inside Chi template

* Rollback to go 1.18 to generate to fix CI
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants