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

Add @ClientFormParam to Reactive REST Client #34535

Merged
merged 1 commit into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 82 additions & 7 deletions docs/src/main/asciidoc/rest-client-reactive.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,82 @@
priority over anything specified in any `@ClientQueryParam` annotation.
====

More information about this annotation can be found on the javadoc of
More information about this annotation can be found on the javadoc of link:https://javadoc.io/doc/io.quarkus/quarkus-rest-client-reactive/latest/io/quarkus/rest/client/reactive/ClientQueryParam.html[`@ClientQueryParam`].

Check warning on line 222 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'Form Parameters'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'Form Parameters'.", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 222, "column": 216}}}, "severity": "INFO"}

=== Form Parameters

Form parameters can be specified using `@RestForm` (or `@FormParam`) annotations:

[source, java]
----
package org.acme.rest.client;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
import org.jboss.resteasy.reactive.RestForm;

import jakarta.ws.rs.PORT;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Consumes;
import jakarta.ws.rs.FormParam;
import jakarta.ws.rs.core.MultivaluedMap;
import java.util.Map;
import java.util.Set;

@Path("/extensions")
@RegisterRestClient(configKey = "extensions-api")
public interface ExtensionsService {

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Set<Extension> postId(@FormParam("id") Integer id);

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Set<Extension> postName(@RestForm String name);

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Set<Extension> postFilter(@RestForm Map<String, String> filter);

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
Set<Extension> postFilters(@RestForm MultivaluedMap<String, String> filters);

}
----

Check warning on line 264 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'Using @ClientFormParam'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'Using @ClientFormParam'.", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 264, "column": 1}}}, "severity": "INFO"}

==== Using @ClientFormParam

Form parameters can also be specified using `@ClientFormParam`, similar to `@ClientQueryParam`:

[source, java]
----
@ClientFormParam(name = "my-param", value = "${my.property-value}")
public interface Client {
@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
String postWithParam();

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@ClientFormParam(name = "some-other-param", value = "other")
String postWithOtherParam();

@POST
@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
@ClientFormParam(name = "param-from-method", value = "{with-param}")
String postFromMethod();

default String withParam(String name) {
if ("param-from-method".equals(name)) {
return "test";
}
throw new IllegalArgumentException();
}
}
----

More information about this annotation can be found on the javadoc of link:https://javadoc.io/doc/io.quarkus/quarkus-rest-client-reactive/latest/io/quarkus/rest/client/reactive/ClientFormParam.html[`@ClientFormParam`].

Check warning on line 297 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Headings] Use sentence-style capitalization in 'Path Parameters'. Raw Output: {"message": "[Quarkus.Headings] Use sentence-style capitalization in 'Path Parameters'.", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 297, "column": 214}}}, "severity": "INFO"}

=== Path Parameters

Expand Down Expand Up @@ -520,9 +595,9 @@
- `quarkus.rest-client.follow-redirects` to enable redirection for all REST clients.
- `quarkus.rest-client.<client-prefix>.follow-redirects` to enable redirection for a specific REST client.

If this property is true, then REST Client will perform a new request that it receives a redirection response from the HTTP server.
If this property is true, then REST Client will perform a new request that it receives a redirection response from the HTTP server.

Additionally, we can limit the number of redirections using the property "max-redirects".

Check warning on line 600 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Spelling] Use correct American English spelling. Did you really mean 'redirections'? Raw Output: {"message": "[Quarkus.Spelling] Use correct American English spelling. Did you really mean 'redirections'?", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 600, "column": 31}}}, "severity": "WARNING"}

One important note is that according to the https://www.rfc-editor.org/rfc/rfc2616#section-10.3.8[RFC2616] specs, by default the redirection will only happen for GET or HEAD methods. However, in REST Client, you can provide your custom redirect handler to enable redirection on POST or PUT methods, or to follow a more complex logic, via either using the `@ClientRedirectHandler` annotation, CDI or programmatically when creating your client.

Expand Down Expand Up @@ -994,7 +1069,7 @@

=== Injecting the `jakarta.ws.rs.ext.Providers` instance in filters

The `jakarta.ws.rs.ext.Providers` is useful when we need to lookup the provider instances of the current client.
The `jakarta.ws.rs.ext.Providers` is useful when we need to lookup the provider instances of the current client.

Check warning on line 1072 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'.", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 1072, "column": 42}}}, "severity": "INFO"}

We can get the `Providers` instance in our filters from the request context as follows:

Expand Down Expand Up @@ -1086,7 +1161,7 @@

=== Using @Blocking annotation in exception mappers

In cases that warrant using `InputStream` as the return type of REST Client method (such as when large amounts of data need to be read):
In cases that warrant using `InputStream` as the return type of REST Client method (such as when large amounts of data need to be read):

Check warning on line 1164 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Rewrite the sentence, or use 'must', instead of' rather than 'need to'.", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 1164, "column": 109}}}, "severity": "INFO"}

[source, java]
----
Expand Down Expand Up @@ -1120,10 +1195,10 @@
}
----

<1> With the `@Blocking` annotation, the MyResponseExceptionMapper exception mapper will be executed in the worker thread pool.
<2> Reading the entity is now allowed because we're executing the mapper on the worker thread pool.
<1> With the `@Blocking` annotation, the MyResponseExceptionMapper exception mapper will be executed in the worker thread pool.
<2> Reading the entity is now allowed because we're executing the mapper on the worker thread pool.

Note that you can also use the `@Blocking` annotation when using @ClientExceptionMapper:

Check warning on line 1201 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.Fluff] Depending on the context, consider using 'Be concise: rewrite the sentence to not use' rather than 'Note that'. Raw Output: {"message": "[Quarkus.Fluff] Depending on the context, consider using 'Be concise: rewrite the sentence to not use' rather than 'Note that'.", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 1201, "column": 1}}}, "severity": "INFO"}

[source, java]
----
Expand Down Expand Up @@ -1288,10 +1363,10 @@

=== Receiving compressed messages
REST Client Reactive also supports receiving compressed messages using GZIP. You can enable the HTTP compression support by adding the property `quarkus.http.enable-compression=true`.
When this feature is enabled and a server returns a response that includes the header `Content-Encoding: gzip`, REST Client Reactive will automatically decode the content and proceed with the message handling.
When this feature is enabled and a server returns a response that includes the header `Content-Encoding: gzip`, REST Client Reactive will automatically decode the content and proceed with the message handling.

== Proxy support
REST Client Reactive supports sending requests through a proxy.

Check warning on line 1369 in docs/src/main/asciidoc/rest-client-reactive.adoc

View workflow job for this annotation

GitHub Actions / Linting with Vale

[vale] reported by reviewdog 🐶 [Quarkus.TermsSuggestions] Depending on the context, consider using '' - ' (range)', 'by using', 'finished', or 'completed' rather than 'through'. Raw Output: {"message": "[Quarkus.TermsSuggestions] Depending on the context, consider using '' - ' (range)', 'by using', 'finished', or 'completed' rather than 'through'.", "location": {"path": "docs/src/main/asciidoc/rest-client-reactive.adoc", "range": {"start": {"line": 1369, "column": 37}}}, "severity": "INFO"}
It honors the JVM settings for it but also allows to specify both:

* global client proxy settings, with `quarkus.rest-client.proxy-address`, `quarkus.rest-client.proxy-user`, `quarkus.rest-client.proxy-password`, `quarkus.rest-client.non-proxy-hosts`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,15 @@ void forSubResourceWebTarget(MethodCreator methodCreator, IndexView index, Class
MethodInfo rootMethod, MethodInfo subMethod, AssignableResultHandle webTarget,
BuildProducer<GeneratedClassBuildItem> generatedClasses);

AssignableResultHandle handleFormParams(MethodCreator methodCreator, IndexView index, ClassInfo interfaceClass,
MethodInfo method, BuildProducer<GeneratedClassBuildItem> generatedClasses,
AssignableResultHandle formParams, boolean multipart);

AssignableResultHandle handleFormParamsForSubResource(MethodCreator methodCreator, IndexView index,
ClassInfo rootInterfaceClass, ClassInfo subInterfaceClass, MethodInfo rootMethod, MethodInfo subMethod,
AssignableResultHandle webTarget, BuildProducer<GeneratedClassBuildItem> generatedClasses,
AssignableResultHandle formParams, boolean multipart);

/**
* Method-level alterations
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,8 @@ A more full example of generated client (with sub-resource) can is at the bottom
enricher.getEnricher()
.forWebTarget(methodCreator, index, interfaceClass, jandexMethod, methodTarget,
generatedClasses);
formParams = enricher.getEnricher().handleFormParams(methodCreator, index, interfaceClass, jandexMethod,
generatedClasses, formParams, multipart);
}

AssignableResultHandle builder = methodCreator.createVariable(Invocation.Builder.class);
Expand Down Expand Up @@ -1660,6 +1662,9 @@ private void handleSubResourceMethod(List<JaxrsClientReactiveEnricherBuildItem>
enricher.getEnricher()
.forSubResourceWebTarget(subMethodCreator, index, interfaceClass, subInterface,
jandexMethod, jandexSubMethod, methodTarget, generatedClasses);
formParams = enricher.getEnricher().handleFormParamsForSubResource(subMethodCreator, index,
interfaceClass, subInterface, jandexMethod, jandexSubMethod, methodTarget, generatedClasses,
formParams, multipart);
}

AssignableResultHandle builder = subMethodCreator.createVariable(Invocation.Builder.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import org.jboss.jandex.DotName;

import io.quarkus.rest.client.reactive.ClientExceptionMapper;
import io.quarkus.rest.client.reactive.ClientFormParam;
import io.quarkus.rest.client.reactive.ClientFormParams;
import io.quarkus.rest.client.reactive.ClientQueryParam;
import io.quarkus.rest.client.reactive.ClientQueryParams;
import io.quarkus.rest.client.reactive.ClientRedirectHandler;
Expand All @@ -27,6 +29,8 @@ public class DotNames {

public static final DotName CLIENT_QUERY_PARAM = DotName.createSimple(ClientQueryParam.class.getName());
public static final DotName CLIENT_QUERY_PARAMS = DotName.createSimple(ClientQueryParams.class.getName());
public static final DotName CLIENT_FORM_PARAM = DotName.createSimple(ClientFormParam.class.getName());
public static final DotName CLIENT_FORM_PARAMS = DotName.createSimple(ClientFormParams.class.getName());
public static final DotName REGISTER_CLIENT_HEADERS = DotName.createSimple(RegisterClientHeaders.class.getName());
public static final DotName CLIENT_REQUEST_FILTER = DotName.createSimple(ClientRequestFilter.class.getName());
public static final DotName CLIENT_RESPONSE_FILTER = DotName.createSimple(ClientResponseFilter.class.getName());
Expand Down
Loading
Loading