-
Notifications
You must be signed in to change notification settings - Fork 287
Add headers to all API methods #1884
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
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much @eric-maynard !
I think it makes a lot of sense to support accepting any headers that the client send, and help people managing their own IRC server, specially since considering IRC client can send any custom headers.
https://github.com/apache/iceberg/commits/main/core/src/main/java/org/apache/iceberg/rest/RESTSessionCatalog.java
would be really nice if we can just add one e2e test !
@@ -132,6 +134,7 @@ public void testUpdateCatalogWithDisallowedStorageConfig() { | |||
.catalogsApi() | |||
.createCatalog( | |||
new CreateCatalogRequest(catalog), | |||
Mockito.mock(HttpHeaders.class), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
would be really nice if we can add some e2e test, for this ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I would love to, but there's nothing actually consuming the headers right now... in a sense, the template change is the actual change, and the test is that we needed to update all the other files in order to make things pass.
String prefix, String namespace, RealmContext realmContext, SecurityContext securityContext) { | ||
String prefix, | ||
String namespace, | ||
HttpHeaders httpHeaders, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WDYT about using a filter plus a request-scoped bean for passing headers to implementation classes?
From my POV that approach:
- Keeps method parameter tuples narrowed down to what is defined in the API
- Affects only the code that needs to know headers
- Can be switched on/off in specific builds / deployments without affecting the main codebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to clarify: normally HttpHeaders
can be injected by CDI automatically in HTTP contexts. A custom bean may be required only to support non-HTTP requests like async tasks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Keeps method parameter tuples narrowed down to what is defined in the API
Plus RealmContext and SecurityContext
Affects only the code that needs to know headers
This sounds like a good alternative but I'm a little unsure how this works. For example, suppose we add some new feature that relied on a custom header passed to e.g. loadTable. We would end up injecting the request-scoped bean into the entire IcebergCatalogAdapter, right? Or is there some way to inject it just into that method?
Can be switched on/off in specific builds / deployments without affecting the main codebase.
Adding the headers here doesn't functionally affect the main codebase, and if you're talking about a nonfunctional impact (e.g. maintenance cost) then it sounds like the proposed alternative would still have that impact?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If IcebergCatalogAdapter
needs heads in any method, the headers will have to be injected all the time (via constructor). However, the methods that do not need the headers will not have to have them in method parameters.
The overhead of this injection is probably negligible because the headers are processed one way or another for every request anyway.
Using method parameters, on the other hand forces all implementations to have those parameters if only one of them actually needs the headers.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if headers are needed in a class N levels down the call chain, the top N-1 levels do not need to pass the headers down - injection will happen into the target object directly (once at level N).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that we need to weigh the pros and cons of each approach. The method signatures are becoming quite big, while components like HttpHeaders
, SecurityContext
(and RealmContext
) are all injectable. Quarkus lists all context objects that are injectable here: https://quarkus.io/guides/rest#accessing-context-objects.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Yeah, this sounds like a good idea. However based on that link, it looks like we should probably be doing the same with with HttpHeaders
that we do with e.g. SecurityContext
?
Why not use the specific |
This is discussed in brief in the description, but there are a couple of points here.
With all this being said, I think using |
Currently, Polaris APIs drop any headers that are not explicitly called out in the API spec.
To support cases where a client may pass in a specific header to control some behavior of the API -- particularly cases where this API is an Iceberg API and we would prefer not to explicitly add the header to the spec -- we can add the headers to the generated methods which handle the REST APIs. This also helps in cases where someone has deployed their own Polaris instance and wants to introduce some custom behavior to an API without changing the spec.