feat: server middleware API - #63
Merged
Merged
Conversation
…active execution uses for events
…sult-aggregation-3
yarolegovich
marked this pull request as ready for review
October 9, 2025 13:27
yarolegovich
force-pushed
the
yarolegovich/call-ctx-api
branch
from
October 9, 2025 13:34
b6fe833 to
c6bbb24
Compare
Member
Author
|
/gemini review |
Contributor
There was a problem hiding this comment.
Code Review
This pull request introduces a server-side middleware API, including support for call interceptors, which is a valuable addition for enhancing extensibility with features like authentication and logging. The implementation is generally robust, featuring a well-designed CallContext and a thorough test suite. My review highlights a few areas for improvement: a bug in the execution order of interceptors, significant code duplication that could be refactored for better maintainability, and a minor code cleanup. I have also suggested an additional test case to ensure the interceptor contract is fully verified.
mazas-google
approved these changes
Oct 28, 2025
yarolegovich
added a commit
that referenced
this pull request
Oct 28, 2025
The integration code for server middleware added in #63: * `a2asrv.WithCallInterceptor` option. * `a2agrpc.Handler` support of metadata conversion.
pull Bot
pushed a commit
to joshuafuller/a2a-go
that referenced
this pull request
Nov 4, 2025
🤖 I have created a release *beep* *boop* --- ## 0.3.0 (2025-11-04) ### Features * add JSON-RPC client transport implementation ([#79](a2aproject#79)) ([1690088](a2aproject@1690088)) * agent card resolver ([#48](a2aproject#48)) ([0951293](a2aproject@0951293)) * blocking flag handling ([#97](a2aproject#97)) ([f7aa465](a2aproject@f7aa465)), closes [#96](a2aproject#96) * client API proposal ([#32](a2aproject#32)) ([b6ca54f](a2aproject@b6ca54f)) * client auth interceptor ([#90](a2aproject#90)) ([25b9aae](a2aproject@25b9aae)) * client interceptor invocations ([#51](a2aproject#51)) ([3e9f2ae](a2aproject@3e9f2ae)) * core types JSON codec ([#42](a2aproject#42)) ([c5b3982](a2aproject@c5b3982)) * define core types and interfaces ([#16](a2aproject#16)) ([69b96ea](a2aproject@69b96ea)) * disallow custom types and circular refs in Metadata ([#43](a2aproject#43)) ([53bc928](a2aproject@53bc928)) * get task implementation ([#59](a2aproject#59)) ([f74d854](a2aproject@f74d854)) * grpc authenticated agent card and producer utils ([#85](a2aproject#85)) ([9d82f31](a2aproject@9d82f31)), closes [#82](a2aproject#82) * grpc client transport ([#66](a2aproject#66)) ([fee703e](a2aproject@fee703e)) * grpc code generation from A2A .proto spec ([#11](a2aproject#11)) ([2993b98](a2aproject@2993b98)) * handling artifacts and implementing send message stream ([#52](a2aproject#52)) ([c3fa631](a2aproject@c3fa631)) * implement an a2aclient.Factory ([#50](a2aproject#50)) ([49deee7](a2aproject@49deee7)) * implementing grpc server wrapper ([#37](a2aproject#37)) ([071e952](a2aproject@071e952)) * implementing message-message interaction ([#34](a2aproject#34)) ([b568979](a2aproject@b568979)) * implementing task pushes ([#86](a2aproject#86)) ([c210240](a2aproject@c210240)) * input-required and auth-required handling ([#70](a2aproject#70)) ([3ac89ba](a2aproject@3ac89ba)) * jsonrpc server ([#91](a2aproject#91)) ([5491030](a2aproject@5491030)) * logger ([#56](a2aproject#56)) ([86ab9d2](a2aproject@86ab9d2)) * request context loading ([#60](a2aproject#60)) ([ab7a29b](a2aproject@ab7a29b)) * result aggregation part 1 - task store ([#38](a2aproject#38)) ([d3c02f5](a2aproject@d3c02f5)) * result aggregation part 3 - concurrent task executor ([#40](a2aproject#40)) ([265c3e7](a2aproject@265c3e7)) * result aggregation part 4 - integration ([#41](a2aproject#41)) ([bab72d9](a2aproject@bab72d9)) * SDK type utilities ([#31](a2aproject#31)) ([32b77b4](a2aproject@32b77b4)) * server middleware API ([#63](a2aproject#63)) ([738bf85](a2aproject@738bf85)) * server middleware integration ([#64](a2aproject#64)) ([5dc8be0](a2aproject@5dc8be0)) * smarter a2aclient ([#88](a2aproject#88)) ([322d05b](a2aproject@322d05b)) * task event factory ([#95](a2aproject#95)) ([fbf3bcf](a2aproject@fbf3bcf)), closes [#84](a2aproject#84) * task executor docs ([#36](a2aproject#36)) ([b6868df](a2aproject@b6868df)) * task update logic ([0ac987f](a2aproject@0ac987f)) ### Bug Fixes * Execute() callers missing events ([#74](a2aproject#74)) ([4c3389f](a2aproject@4c3389f)) * mark task failed when execution fails ([#94](a2aproject#94)) ([ee0e7ed](a2aproject@ee0e7ed)) * push semantics update ([#93](a2aproject#93)) ([76bff9f](a2aproject@76bff9f)) * race detector queue closed access ([c07b7d0](a2aproject@c07b7d0)) * regenerate proto and update converters ([#81](a2aproject#81)) ([c732060](a2aproject@c732060)) * streaming ([#92](a2aproject#92)) ([ca7a64b](a2aproject@ca7a64b)) ### Miscellaneous Chores * release 0.3.0 ([fa7cfba](a2aproject@fa7cfba)) --- This PR was generated with [Release Please](https://github.com/googleapis/release-please). See [documentation](https://github.com/googleapis/release-please#release-please).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Details
Changes in the
a2asrvpackage required for providing extensions and auth support.CallContext
CallContextstruct can be accessed usingCallContextFrom(context.Context)and will hold the following information:RequestMetaimmutable struct used for accessing data like headers, signatures, etc. Lookups are case-insensitive.activatedExtensions. This list should be updated by extension implementers usingCallContext.Activate(self).Userinterface which holds auth-related information. It's an interface to allow passing custom types here.Transport implementations can pass
RequestMetaby usingctx, callCtx := WithCallContext(ctx, toRequestMeta(transportSpecificMeta)). The returnedcallCtxcan be used to examine which extensions were activated during request processing.Some transports might decide whether to attach activated extensions to a response. SSE for example requires headers to be passed before the first response chunk. gRPC attaches extensions as a metadata trailer.
CallInterceptor
CallInterceptorAPI-wise is similar toa2aclient.CallInterceptor.BeforeandAftermethods can be used to observe, reject or modify requests and responses.CallContextis passed to these methods explicitly because interceptors will likely be often used for extensions and auth.InterceptedHandler
InterceptedHandlerimplementsRequestHandlerand helps to ensure correct interceptor invocations without the need to track early returns (something we would need to do if integrating interceptors into the defaultRequestHandler). It is exported so that SDK user can use it to add interceptor functionality to their RequestHandler implementation if a custom one is used.