Skip to content

Implements possibility to disable @Param url encoding#465

Merged
codefromthecrypt merged 6 commits into
OpenFeign:masterfrom
parkee:master
Oct 1, 2016
Merged

Implements possibility to disable @Param url encoding#465
codefromthecrypt merged 6 commits into
OpenFeign:masterfrom
parkee:master

Conversation

@parkee

@parkee parkee commented Sep 26, 2016

Copy link
Copy Markdown
Contributor

Now it is possible with @Param(encoded = true) to disable hardcoded call of urlEncode method on every @Param
This helps to implement matrix params or send unencoded path variables or query parameters which is required by some APIs

@codefromthecrypt codefromthecrypt left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Mind adding some tests to exemplify this? Also, can you note which api this helps with? (being concrete is always better)

protected RequestTemplate resolve(Object[] argv, RequestTemplate mutable,
Map<String, Object> variables) {
return mutable.resolve(variables);
final HashMap<String, Boolean> variableToEncoded = new HashMap<String, Boolean>();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LinkedHashMap pls

@parkee

parkee commented Sep 26, 2016

Copy link
Copy Markdown
Contributor Author

Added one test to exemplify this behaviour and changed HashMap to LinkedHashMap
We are using matrix params in one of out internal API
Also wheel-size api will not accept encoded parameter: i.e. trim should be "5.2FSi+", not "5.2FSi%2b":
So this request won't work
https://api.wheel-size.com/v1/vehicles/?user_key=USER_KEY&make=audi&model=r8&year=2015&trim=5.2FSi%2b
But not encoded will:
https://api.wheel-size.com/v1/vehicles/?user_key=USER_KEY&make=audi&model=r8&year=2015&trim=5.2FSi+
In some cases it would be path variable, not query parameter

@codefromthecrypt codefromthecrypt left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

some changes, also need to update CHANGES. very close!

ps thanks for the help

Comment thread core/src/main/java/feign/Contract.java Outdated
String name = ((Param) annotation).value();
checkState(emptyToNull(name) != null, "Param annotation was empty on param %s.",
paramIndex);
final Param paramAnnotation = (Param) annotation;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit we don't usually mark locals final unless doing so is notable (ex used in an anonymous type)

String name = paramAnnotation.value();
checkState(emptyToNull(name) != null, "Param annotation was empty on param %s.", paramIndex);
nameParam(data, name, paramIndex);
if (annotationType == Param.class) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

weird.. we actually checked twice :P

data.indexToEncoded().put(paramIndex, paramAnnotation.encoded());
isHttpAnnotation = true;
String varName = '{' + name + '}';
if (data.template().url().indexOf(varName) == -1 &&

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

fair enough!

Comment thread core/src/main/java/feign/Param.java Outdated

/**
* Specifies whether argument is already encoded
* Value be ignored for headers (headers are never encoded)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

good clarification

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

probably should also put @see QueryMap#encoded as well putting a see link there back to here

protected RequestTemplate resolve(Object[] argv, RequestTemplate mutable,
Map<String, Object> variables) {
return mutable.resolve(variables);
final Map<String, Boolean> variableToEncoded = new LinkedHashMap<String, Boolean>();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

add a comment of what's going on here. (also pls unfinal the locals)

map.put(key, values);
}

public RequestTemplate resolve(Map<String, ?> unencoded) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

add see link

ex.

/** like {@link #resolve(Map, Map)}, which assumes no parameter is encoded */

* Replaces query values which are templated with corresponding values from the {@code unencoded}
* map. Any unresolved queries are removed.
*/
public void replaceQueryValues(Map<String, ?> unencoded) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

does this break api? if so, please add an overload

void queryMapWithQueryParams(@Param("name") String name, @QueryMap Map<String, Object> queryMap);

@RequestLine("GET /?trim={trim}")
void encodedQueryParam(@Param(value = "trim", encoded = true) String trim);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nice

* Replaces query values which are templated with corresponding values from the {@code unencoded}
* map. Any unresolved queries are removed.
*/
public void replaceQueryValues(Map<String, ?> unencoded) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

please overload with the prior signature so that we don't break other people's code.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

? It's already done.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

diff problem no worries

* map. Any unresolved queries are removed.
*/
public void replaceQueryValues(Map<String, ?> unencoded) {
public void replaceQueryValues(Map<String, ?> unencoded, Map<String, Boolean> alreadyEncoded) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

does this need to be public (ex are you using this directly?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I see no reason in original method being public either, so I decided to leave overloaded one public too to be consistent.
Should I make new method private instead of overloading public method?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

package private por favor

Comment thread CHANGELOG.md Outdated
@@ -1,5 +1,6 @@
### Version 9.3
* Adds `FallbackFactory`, allowing access to the cause of a Hystrix fallback
* Adds support for encoded parameters in @Param via @Param(encoded = true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

simplify and format? Ex.

  • Adds support for encoded parameters via @Param(encoded = true)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ok

@codefromthecrypt codefromthecrypt left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

k just some nits, then lets merge this

Comment thread CHANGELOG.md Outdated
@@ -1,5 +1,6 @@
### Version 9.3
* Adds `FallbackFactory`, allowing access to the cause of a Hystrix fallback
* Adds support for encoded parameters via @Param(encoded = true)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit, if you get used to doing backticks, not only will the format look nicer, but you won't accidentally mention someone named Param :P

*/
public RequestTemplate resolve(Map<String, ?> unencoded) {
replaceQueryValues(unencoded);
public RequestTemplate resolve(Map<String, ?> unencoded, Map<String, Boolean> alreadyEncoded) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

for this and below, package private is fine (as opposed to private). these are new methods, so we can hide them until someone asks. package private is better as it can be tested directly (plus the bytecode is smaller)

* Replaces query values which are templated with corresponding values from the {@code unencoded}
* map. Any unresolved queries are removed.
*/
public void replaceQueryValues(Map<String, ?> unencoded) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

diff problem no worries

* map. Any unresolved queries are removed.
*/
public void replaceQueryValues(Map<String, ?> unencoded) {
public void replaceQueryValues(Map<String, ?> unencoded, Map<String, Boolean> alreadyEncoded) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

package private por favor

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