Skip to content
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

SpringMvcContract support parse params #1016

Merged
merged 4 commits into from
May 13, 2024

Conversation

Puppy4C
Copy link
Contributor

@Puppy4C Puppy4C commented Apr 4, 2024

Previously, SpringMvcContract did not support parsing the params parameter of @RequestMapping.

Example:

  1. Define a rest interface that uses the params parameter:
@PutMapping(value = "/user", params = "action=disable")
public String disableUser() {
    return "user";
}
  1. Define a FeignClient to call the previously declared interface:
@FeignClient("user-server")
static interface UserService {
    @PutMapping(value = "/user", params = "action=disable")
    String disableUser();
}

When sending this request, the request path will be resolved to /user instead of /user?action=disable, resulting in 400 errors.
Therefore, this PR provides the ability to parse params parameter.

@pivotal-cla
Copy link

@Puppy4C Please sign the Contributor License Agreement!

Click here to manually synchronize the status of this Pull Request.

See the FAQ for frequently asked questions.

@pivotal-cla
Copy link

@Puppy4C Thank you for signing the Contributor License Agreement!

Copy link
Collaborator

@OlgaMaciaszek OlgaMaciaszek left a comment

Choose a reason for hiding this comment

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

Thanks for the PR, @Puppy4C. Have added some comments - please take a look.

@@ -354,6 +358,19 @@ private void parseHeaders(MethodMetadata md, Method method, RequestMapping annot
}
}

private void parseParams(MethodMetadata data, Method method, RequestMapping methodMapping) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add documentation for this feature in spring-cloud-openfeign.adoc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

NameValueResolver(String expression) {
int separator = expression.indexOf('=');
if (separator == -1) {
this.isNegated = expression.startsWith("!");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please remove unnecessary this. keywords.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

@@ -462,6 +463,60 @@ void testProcessAnnotations_MapParams() throws Exception {
assertThat(data.queryMapIndex().intValue()).isEqualTo(0);
}

@Test
void testProcessAnnotations_ParseParams_SingleParam() throws Exception {
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a tests to verify behaviour when both params= and @RequestParam annotation present.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed

}
for (String param : params) {
NameValueResolver nameValueResolver = new NameValueResolver(param);
if (!nameValueResolver.isNegated()) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I know it was handled for headers, but it actually does not make much sense to have negated values on client side; I think we should not handle them at all (i.e. throw an exception), because adding them on client side indicates the client-side API has not been thought through.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's good. Fixed

@OlgaMaciaszek OlgaMaciaszek added enhancement New feature or request and removed waiting-for-triage labels Apr 18, 2024
@OlgaMaciaszek OlgaMaciaszek self-assigned this Apr 18, 2024
@OlgaMaciaszek OlgaMaciaszek added this to the 4.1.2 milestone Apr 18, 2024
Copy link
Collaborator

@OlgaMaciaszek OlgaMaciaszek left a comment

Choose a reason for hiding this comment

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

Thanks @Puppy4C. The implementation looks good, but the documentation should be slightly more robust. I have added a comment. Please address.

@@ -45,7 +45,7 @@ public interface StoreClient {
@GetMapping("/stores")
Page<Store> getStores(Pageable pageable);
@PostMapping(value = "/stores/{storeId}", consumes = "application/json")
@PostMapping(value = "/stores/{storeId}", consumes = "application/json", params = "mode=upsert")
Copy link
Collaborator

Choose a reason for hiding this comment

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

Please add a description of the feature, including information on what syntax is allowed and to what resulting query params it will be resolved.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Copy link
Collaborator

@OlgaMaciaszek OlgaMaciaszek left a comment

Choose a reason for hiding this comment

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

Thanks @Puppy4C. LGTM.

@OlgaMaciaszek
Copy link
Collaborator

@Buzzardo could you please review the documentation changes?

[[spring-requestmapping-support]]
=== Spring @RequestMapping Support

Spring Cloud OpenFeign provides support for the Spring `@RequestMapping` annotation and its derived annotations (such as `@GetMapping`, `@PostMapping`, etc.) support.
Copy link

Choose a reason for hiding this comment

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

Change etc. to and others.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done, thanks a lot!

=== Spring @RequestMapping Support

Spring Cloud OpenFeign provides support for the Spring `@RequestMapping` annotation and its derived annotations (such as `@GetMapping`, `@PostMapping`, etc.) support.
The attributes on the `@RequestMapping` annotation (including `value`, `method`, `params`, `headers`, `consumes`, and `produces`) will be parsed by `SpringMvcContract` as the content of the request.
Copy link

Choose a reason for hiding this comment

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

Change will be to are.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

The attributes on the `@RequestMapping` annotation (including `value`, `method`, `params`, `headers`, `consumes`, and `produces`) will be parsed by `SpringMvcContract` as the content of the request.


For example:
Copy link

Choose a reason for hiding this comment

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

Change to Consider the following example:

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

}
----

In the above example, the request url will be resolved to `/stores/{storeId}?mode=upsert`. +
Copy link

Choose a reason for hiding this comment

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

Change will be to is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

----

In the above example, the request url will be resolved to `/stores/{storeId}?mode=upsert`. +
The params attribute also supports the use of multiple `key=value` or only one `key`. For example: +
Copy link

Choose a reason for hiding this comment

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

Remove . For example

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

In the above example, the request url will be resolved to `/stores/{storeId}?mode=upsert`. +
The params attribute also supports the use of multiple `key=value` or only one `key`. For example: +

- When `params = { "key1=v1", "key2=v2" }`, the request url will be parsed as `/stores/{storeId}?key1=v1&key2=v2`.
Copy link

Choose a reason for hiding this comment

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

Change will be to is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

The params attribute also supports the use of multiple `key=value` or only one `key`. For example: +

- When `params = { "key1=v1", "key2=v2" }`, the request url will be parsed as `/stores/{storeId}?key1=v1&key2=v2`.
- When `params = "key"`, the request url will be parsed as `/stores/{storeId}?key`.
Copy link

Choose a reason for hiding this comment

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

Change will be to is.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

@OlgaMaciaszek
Copy link
Collaborator

Thanks a lot @Buzzardo. @Puppy4C please apply the documentation changes suggested by @Buzzardo.

@Puppy4C
Copy link
Contributor Author

Puppy4C commented May 9, 2024

Hi @OlgaMaciaszek,Done

@Puppy4C Puppy4C requested a review from OlgaMaciaszek May 9, 2024 14:00
Copy link
Collaborator

@OlgaMaciaszek OlgaMaciaszek left a comment

Choose a reason for hiding this comment

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

Thanks @Puppy4C. LGTM.

@OlgaMaciaszek OlgaMaciaszek merged commit c276f1c into spring-cloud:main May 13, 2024
2 checks passed
natedanner pushed a commit to natedanner/spring-cloud__spring-cloud-openfeign that referenced this pull request May 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

None yet

5 participants