se.guides.webclient.adoc Maven / Gradle / Ivy
///////////////////////////////////////////////////////////////////////////////
Copyright (c) 2021, 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
///////////////////////////////////////////////////////////////////////////////
= Helidon SE WebClient Guide
:description: Helidon WebClient
:keywords: helidon, WebClient, web, client
:rootdir: {docdir}/../..
include::{rootdir}/includes/se.adoc[]
This guide describes how to create a sample Helidon SE project
that can be used to run some basic examples using WebClient.
== What you need
For this 15 minute tutorial, you will need the following:
include::{rootdir}/includes/prerequisites.adoc[tag=prerequisites]
* <>
* <>
* <>
=== WebClient Features [[WebClient-features]]
Helidon's WebClient is used to perform HTTP REST requests to target endpoints and handle their responses.
*Note*: WebClient is still experimental and not intended for production use. APIs and features are not yet fully tested
and are subject to change.
WebClient provides the following features:
* *User-friendly*:
Every client and request is created by a builder pattern, so it improves readability and code maintenance.
* *Following redirects*:
The WebClient is able to follow the redirect chain and perform requests on the correct endpoint for you. You no longer
have to point your client to the correct/final endpoint.
* *Tracing, metrics and security propagation*:
When you configure the Helidon WebServer to use tracing, metrics and security, the settings are automatically
propagated to the WebClient and used during request/response.
For more information about the `WebClient`, please refer to the xref:../webclient.adoc[WebClient Introduction].
=== WebClient Usage [[WebClient-usage]]
==== Create a sample SE project
Generate the project sources using the Helidon SE Maven archetype.
The result is a simple project that can be used for the examples in this guide.
[source,bash,subs="attributes+"]
.Run the Maven archetype:
----
mvn -U archetype:generate -DinteractiveMode=false \
-DarchetypeGroupId=io.helidon.archetypes \
-DarchetypeArtifactId=helidon-quickstart-se \
-DarchetypeVersion={helidon-version} \
-DgroupId=io.helidon.examples \
-DartifactId=helidon-quickstart-se \
-Dpackage=io.helidon.examples.quickstart.se
----
You should now have a directory called `helidon-quickstart-se`.
[source,bash]
.Open this directory
----
cd helidon-quickstart-se
----
The Helidon quickstart is a greeting application supporting several HTTP requests such as GET and PUT. Using it will
be time-saving for this exercise as it will allow us to modify the project to demonstrate some of the Webclient features and usability, rather than start from scratch.
==== Add ClientExample class
In `io.helidon.examples.quickstart.se` package, create a new class named ClientExample. This class will use the
WebClient to send request to the greeting application.
[source,java]
.Create ClientExample class:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_1, indent=0]
----
Add the following code to the main method to create a WebClient instance.
The builder approach allows you to create the WebClient with specific settings and improves the readability and simplicity of the
code.
[source,java]
.Add WebClient instance to the main method:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_2, indent=0]
----
<1> The base URI of the outbound requests.
By default, the Helidon quickstart application runs on localhost:8080. If for some reason the host name or port
number of the quickstart application is changed, make sure that the baseURI is also modified to reflect that change.
Once built, the WebClient can
be used to send a GET request to the greeting application.
[source,java]
.Send a GET request to the target endpoint:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_3, indent=0]
----
<1> Create an HTTP GET request.
<2> Target endpoint path.
<3> Execute the request
<4> Return response entity handled as a String.
The path method appends `/greet` to the WebClient base URI which results to the request URI becoming
`http://localhost:8080/greet`. The received response entity will be a greeting message and will be
automatically handled as a String. If no specific type is set in the method request(),
`HttpClientResponse` will be returned by default. This `HttpClientResponse` object contains response code, headers and entity.
==== Run the application
[source,bash]
.Build the quickstart:
----
mvn package
----
This command will create helidon-quickstart-se.jar in the target folder.
[source,bash]
.Run the greeting application:
----
java -cp target/helidon-quickstart-se.jar io.helidon.examples.quickstart.se.Main
----
Open a new command prompt or terminal and run the ClientExample class you just created.
[source,bash]
.Run the client application:
----
java -cp target/helidon-quickstart-se.jar io.helidon.examples.quickstart.se.ClientExample
----
[source,json]
.JSON response:
----
{"message":"Hello World!"}
----
When the ClientExample finishes its execution, you can stop the Main class by pressing `CTRL+C`.
==== Discover other WebClient functionality
In practice, String is not the most useful return type, since it usually needs some more handling. In this case, it
could be more interesting to return an object of another type like a JSON object. One way to process a JSON object is
by enabling Helidon's built-in JSON-P support and this can be simply achieved by adding its dependency in the project's pom.xml:
[source,xml]
----
io.helidon.http.media
helidon-http-media-jsonp
----
Once the dependency is added, the feature will be automatically loaded as a service allowing the response methods to
easily parse the JSON object.
[source,java]
.Replace String with JsonObject:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_4, indent=0]
----
<1> Request a JsonObject as return value.
<2> Extract the value of the JsonObject with name of `message`.
In the URI, the String value following `greet` is a path parameter which allows the application to greet someone.
[source,bash]
.Output:
----
Hello David!
----
It is also possible to change the greeting word by using a PUT request to `/greet/greeting` path. The request also
needs to include a body with JSON type and using a structure like `pass:[{"greeting" : "value"}]`.
[source,java]
.Modify the application greeting:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_5, indent=0]
----
<1> Create a JsonObject with key `greeting` and value `bonjour`.
<2> Create a PUT request.
<3> Submit the JsonObject created earlier.
<4> Execute a GET call to verify that the greeting has been changed.
<5> Retrieve the greeting message from the JSON object
Executing the above code will yield this output showing that the greeting word has been changed.
[source,bash]
.Output:
----
Bonjour David!
----
=== WebClient Metrics [[WebClient-Metrics]]
WebClient, like other Helidon components, supports Metrics. The following example introduces a counter metric that
can be used to measure WebClient request activity. There are two ways to set up metrics, programmatically on the
WebClient instance or manually using the configuration file.
==== Add metrics dependency
To enable support for this feature, the `helidon-webclient-metrics` dependency needs to be added .
[source,xml]
.Add the following dependency to pom.xml:
----
io.helidon.webclient
helidon-webclient-metrics
----
==== Set up metrics on WebClient instance
Metrics can be registered on the WebClient directly.
The following example shows how a `Counter` metric can be defined, created and monitored.
[source,java]
.Example of metric creation:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_6, indent=0]
----
<1> Specify the metric name.
<2> From the `MeterRegistry`, create a Counter metric using the specified metric name.
<3> Specify how the name of the metric will be generated using the `nameFormat`.
<4> Build a WebClient Metric Service that can count number of GET requests made.
In this example, the metric uses a `Counter` to measure the number of `GET` requests executed on the `localhost`.
The format strings in the parameter value of `nameFormat` method will identify how the name of a metric will get
generated:
* `%1$s` = Request method
* `%2$s` = Request host
* `%3$s` = Response status
So for example, if the `nameFormat` value is `metric.%1$s.%2$s.%3$s` and a request uses a GET method, targeting a URL with localhost as the hostname, and got a response code of 200, that the final metric will get created with a name of metric.GET.localhost.200.
To register the metric service, simply use the `addService` method and pass in the created WebClient Metric Service as a
parameter.
[source,java]
.Add the metric service to the WebClient:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_7, indent=0]
----
<1> Register the metric service to the webclient.
<2> Send an HTTP GET request
To verify that the metric is set up correctly, print the value of the Counter at the end of the main method.
[source,java]
.Print the metric count
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_8, indent=0]
----
This will result to an output showing that a metric with the name of `counter.GET.localhost` was created with
a count value of 1 indicating that it correctly measured the request that was just made.
[source,bash]
.Output:
----
counter.GET.localhost: 1
----
==== Set up metrics with configuration files
Using the configuration file can reduce the code complexity and make the metrics simpler to use. With this approach,
it eliminates the need to modify the source code for scenarios where the metric settings have to be changed.
The `application.yaml` file is the default configuration file for Helidon and can be used to set up metrics settings.
[source,yaml]
.Example of metric configuration:
----
client:
services:
metrics:
- type: COUNTER
methods: ["GET"]
description: "Metric Description"
name-format: "counter.%1$s.%2$s"
----
In the example configuration definition above, the metrics configuration are located under `client.services.metrics`.
The metric setting can start either by its `type` or `methods`. The configuration file uses the same keywords as the
programmatic way. For example, `type` defines the kind of metric and `methods` identifies the http methods that will
be measured.
[source,java]
.Add the metric service to the WebClient via the Configuration:
----
include::{sourcedir}/se/guides/WebclientSnippets.java[tag=snippet_9, indent=0]
----
<1> Choose the metric name.
<2> Create counter metric from `MeterRegistry`.
<3> Create a Helidon Config instance from default config file `application.yaml`.
<4> Configure the WebClient using the `client` section from `application.yaml`.
<5> Send an HTTP GET request
<6> Print out the metric result
As demonstrated, using the configuration file reduces the amount of code needed in the source code. For more information
about metrics, see the xref:metrics.adoc[Helidon Metrics Guide].
© 2015 - 2025 Weber Informatics LLC | Privacy Policy