Skip to content

Execute metadata interceptors at the start of the chain before parsing request - #328

Merged
anuraaga merged 1 commit into
connectrpc:mainfrom
anuraaga:split-leading-metadata
Sep 4, 2026
Merged

Execute metadata interceptors at the start of the chain before parsing request#328
anuraaga merged 1 commit into
connectrpc:mainfrom
anuraaga:split-leading-metadata

Conversation

@anuraaga

@anuraaga anuraaga commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

Even though metadata interceptors don't need the request payload, they are always executed after parsing it. While we recommend using ASGI middleware for i.e. auth, still it's not that hard for us to also allow leading metadata interceptors to run before parse and can make sure an interceptor can block a bad / malicious request before parsing it if a user chooses to do it in an interceptor.

…g messages

Signed-off-by: Anuraag Agrawal <anuraaga@gmail.com>
@anuraaga
anuraaga requested a review from a team September 2, 2026 03:50

@stefanvanburen stefanvanburen left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

seems ok - stepping back though, special-casing the metadata interceptors at the front of the list for servers feels not great from a discoverability perspective. Any other Python APIs act similarly to this? anything we ought to learn from connect-go's v2 design that we ought to change here before we get to v1?

@anuraaga

anuraaga commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator Author

Good callout that deserved more explanation - here it's actually intentional to go for lower discoverability to continue to recommend middleware for auth, rate limiting etc, which I lean towards given how much i.e starlette provides. So this is more of a silent optimization / escape hatch since it's not that hard to do.

I'm still ok though with giving it more discoverability / first class treatment by separating out metadata_interceptors= which are always applied before request parsing, and not allow passing metadata interceptors to interceptors=. This would preserve the current interceptor API. I tend to like the current interceptor API itself where interceptors mostly match service implementations as-is to keep them intuitive. The alternative would be for interceptors to return handlers, not responses. Python's limited lambdas / tricky inner function syntax makes returning handlers not quite as nice, but happy to explore it if it seems worthwhile.

Any thoughts on any of the above?

@stefanvanburen

Copy link
Copy Markdown
Member

I'm still ok though with giving it more discoverability / first class treatment by separating out metadata_interceptors= which are always applied before request parsing, and not allow passing metadata interceptors to interceptors=.

Splitting them out is tempting, but thinking on it more: is there a good reason to ever want to run a metadata interceptor after a regular interceptor has run? I suspect there might be (not coming up with one this morning quite yet).

With that, I guess I'm leaning more towards leaving the API as-is and leaning heavily on the docs to prefer metadata interceptors where possible and put them up front in the interceptor chain (as it looks like you're doing)?

Thanks for the discussion, just wanted to call this out before landing.

@anuraaga

anuraaga commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author

is there a good reason to ever want to run a metadata interceptor after a regular interceptor has run? I suspect there might be

I think technically the answer is no since in their current form they are just syntactic sugar for a regular interceptor - so if splitting, such an interceptor could be written as a normal interceptor, more verbose but not hard.

But will stick to this for now since it's API-neutral, let me know if still any thoughts to improve it!

@anuraaga
anuraaga merged commit e2f74e5 into connectrpc:main Sep 4, 2026
24 checks passed
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.

2 participants