-
Notifications
You must be signed in to change notification settings - Fork 7.3k
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
Allow parameters with custom annotations in service methods #3464
base: trunk
Are you sure you want to change the base?
Conversation
I'm not satisfied with the implementation as-is, but I'm not opposed to the idea. We've long wanted custom parameter annotations which support things like arbitrarily mutating the request but it's a complicated thing to implement with a large API surface. The biggest problem that I see on first glance is that it's far too easy to create an argument that does nothing. At the very least I would want each annotation to be registered and arguments with no built-in nor registered annotations are still a failure. This would ensure, at the very least, that an argument is never simply dropped. I'm not sure whether it's worth it to add this feature as-is or in a similar manner to as proposed or try to tackle the larger problem of completely arbitrary arguments which can mutate things like how the request is created. We already have this mechanism internally, but this would mean exposing it in a general way. Also there are no tests so before doing anything we need to ensure coverage. |
Thanks for your feedback. I have updated the PR to include the required unit test so custom annotations have test coverage. I agree with your statement that a more integrated way of providing handlers for custom annotations would be better. To support this I think we need to do the following:
This way developers can add custom parameter handlers to retrofit. Using the existing methods on RequestFactory.Builder this ParameterHandler can modify the request good enough I think. Another possibility would be to also expose the private OkHttp Request.Builder, so you can do literally everything, but I am not sure if that is a good idea or not. I think I will have time to create a separate PR for the better approach, so we can compare them. @JakeWharton Can you give your opinion on this proposed solution? p.s. |
I have attempted to implement a better way of supporting custom parameter annotations, but my first intuition of using ParameterHandlers and making the retrofit.RequestBuilder class public became quite a mess and also did not solve the problem completely. Instead I opted for a more naive approach where the developer has full freedom over the request if he so pleases. See this PR What I found out when trying to implement custom parameter annotations in the way described in my previous comment is the following:
|
What
Support for parameters with custom annotations.
For example:
Why
When implementing a custom
Call.Factory
implementation, its nice to be able to access custom data provided to the request. We can access theInvocation
from the newCall method, which can be used to inspect all annotations (both method and parameter annotations), as well as the arguments provided. Using this we can access what value is provided for the argument annotated with@CustomAnnotation
. See example below:In my particular use-case, I want to use this for a
@ForceRefresh
annotation, since I am trying to implement a secure caching solution (protected by an app specific pincode and AndroidKeystore, backed by an sqlcipher database), and sometimes you dont want to use the cache (hence the ForceRefresh annotation). Custom method annotations is not an issue luckily, but custom argument annotations are not supported yet.How
Don't throw the
No Retrofit annotation found.
exception, but instead only throw an exception when there is a parameter without any annotation. Furthermore I made the logic that applies the handlers null-aware for this and I updated the unit test assertion.