Configure the HTTP client
Quarkus Flow supports calling external services over HTTP and OpenAPI. All HTTP / OpenAPI tasks share a common, tunable HTTP client layer powered by RESTEasy Reactive and Vert.x.
This guide shows how to:
-
understand which HTTP client Quarkus Flow uses for a given workflow / task
-
configure the default HTTP client
-
define named HTTP clients
-
route specific workflows / tasks to a named client
-
configure static headers, logging, proxy, TLS and other network options
The low-level configuration reference for all HTTP properties lives in the
Extension Configuration Reference page under
the quarkus.flow.http.client.* namespace.
|
Prerequisites
-
A Quarkus application with Quarkus Flow set up.
-
At least one workflow that uses HTTP or OpenAPI tasks (see Call HTTP and OpenAPI services).
-
Basic familiarity with Quarkus configuration.
1. Understand the HTTP client model
All Flow HTTP / OpenAPI tasks use a jakarta.ws.rs.client.Client managed by Quarkus Flow.
At runtime, Quarkus Flow:
-
builds a default client from
quarkus.flow.http.client.* -
optionally builds named clients from
quarkus.flow.http.client.named.<name>.* -
resolves which client to use for a given workflow + task using
quarkus.flow.http.client.workflow.*routing -
reuses and closes these clients automatically for you at the end of the application lifecycle
Internally, the extension maps these configuration properties to a RESTEasy Reactive
ClientBuilderImpl and Vert.x HttpClientOptions, but the API you configure is purely
Quarkus Flow configuration.
2. Configure the default HTTP client
The default HTTP client is used when no routing is configured for a workflow or task.
All default client properties live under:
quarkus.flow.http.client.<property>=<value>
Common examples:
# Basic timeouts (milliseconds)
quarkus.flow.http.client.connect-timeout=5000
quarkus.flow.http.client.read-timeout=10000
# HTTP connection pool and keep-alive
quarkus.flow.http.client.connection-pool-size=50
quarkus.flow.http.client.keep-alive-enabled=true
quarkus.flow.http.client.connection-ttl=60
# User agent
quarkus.flow.http.client.user-agent=quarkus-flow/1.0
These settings apply to all HTTP / OpenAPI tasks unless a more specific named client is selected via routing.
3. Create named HTTP clients
You can declare as many named HTTP clients as you need, each with its own tuning (timeouts, headers, logging, proxy, etc.).
Named clients live under:
quarkus.flow.http.client.named.<name>.<property>=<value>
Example: two named clients, secureA and internal:
# "secureA" – external API with strict timeouts and custom UA
quarkus.flow.http.client.named.secureA.connect-timeout=3000
quarkus.flow.http.client.named.secureA.read-timeout=8000
quarkus.flow.http.client.named.secureA.user-agent=MyCompanyBot/1.0
quarkus.flow.http.client.named.secureA.logging.scope=request-response
quarkus.flow.http.client.named.secureA.logging.body-limit=256
quarkus.flow.http.client.named.secureA.static-headers=X-Env=prod,X-Tenant=acme
# "internal" – internal service with a larger pool and relaxed timeouts
quarkus.flow.http.client.named.internal.connect-timeout=1000
quarkus.flow.http.client.named.internal.read-timeout=20000
quarkus.flow.http.client.named.internal.connection-pool-size=100
quarkus.flow.http.client.named.internal.keep-alive-enabled=true
If a named client is resolved but not configured, Quarkus Flow falls back to the default HTTP client.
4. Route workflows and tasks to clients
Routing is configured under the workflow section of the HTTP config:
# Use "secureA" for all HTTP/OpenAPI tasks in workflow "order-flow"
quarkus.flow.http.client.workflow.order-flow.name=secureA
# Override only the "fetchCustomers" task in "order-flow" to use "internal"
quarkus.flow.http.client.workflow.order-flow.task.fetchCustomers.name=internal
Resolution order for a call:
-
Task-level override:
quarkus.flow.http.client.workflow.<workflowId>.task.<taskId>.name -
Workflow-level default:
quarkus.flow.http.client.workflow.<workflowId>.name -
Fallback to the global default client (
quarkus.flow.http.client.*)
Here, <workflowId> is the workflow id (from the Workflow DSL),
and <taskId> is the HTTP/OpenAPI task name.
| Although you can have an inner task named the same as a parent task per specification, for HTTP clients it’s highly recommended that you keep HTTP-related task names unique. |
5. Configure static headers
Use static-headers to attach headers to every request sent by a client.
The value is a comma-separated list of name=value pairs:
# Default client
quarkus.flow.http.client.static-headers=X-Env=prod,X-Tenant=acme
# Named client "secureA"
quarkus.flow.http.client.named.secureA.static-headers=X-Env=prod,X-Region=us-east-1
Rules:
-
entries are separated by commas
, -
each entry must be
name=value -
whitespace around names/values is ignored
-
invalid entries are ignored with a warning in the logs
Example:
quarkus.flow.http.client.static-headers=X-Env=prod,X-Tenant=acme
results in:
-
X-Env: prod -
X-Tenant: acme
on every request performed by the selected client.
6. Logging and debugging HTTP requests
When wiring workflows to external HTTP or OpenAPI services, seeing the actual requests and responses is crucial for debugging.
Quarkus Flow reuses the RESTEasy Reactive client logger, which you can enable and tune
via quarkus.flow.http.client.* and standard Quarkus logging categories.
Enable request/response logging
At minimum, set the logging scope for the HTTP client and turn on DEBUG logging for the REST client logger:
# Log both request and response line + headers (+ body, see below)
quarkus.flow.http.client.logging.scope=request-response
# Truncate logged body after N characters
quarkus.flow.http.client.logging.body-limit=1024
# Enable the REST client logger
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
The logging.scope property maps to LoggingScope:
-
none– no logging (default) -
request-response– log one line per request/response, plus headers and body (up tologging.body-limitchars) -
all– most verbose; includes additional internal details
The logging.body-limit controls how much of the request/response body is included
in the logs, helping avoid flooding your logs with very large payloads.
You can configure them per named client:
quarkus.flow.http.client.named.secureA.logging.scope=request-response
quarkus.flow.http.client.named.secureA.logging.body-limit=256
quarkus.flow.http.client.named.internal.logging.scope=none
The logging category stays the same:
quarkus.log.category."org.jboss.resteasy.reactive.client.logging".level=DEBUG
Once enabled, every HTTP/OpenAPI task that uses those clients will emit debug logs with the full HTTP interaction, which is especially useful when iterating on workflow definitions or diagnosing failures against third-party APIs.
7. HTTP/2 and ALPN
You can enable HTTP/2 and ALPN per client:
# Default client
quarkus.flow.http.client.http2=true
quarkus.flow.http.client.alpn=true
# Named client
quarkus.flow.http.client.named.secureA.http2=true
quarkus.flow.http.client.named.secureA.alpn=true
Quarkus Flow passes these flags to the underlying Vert.x HttpClientOptions.
If you also configure TLS, ALPN is used to negotiate the protocol when supported
by the server.
8. Proxy support
Proxy support is exposed as a thin layer over the RESTEasy Reactive ClientBuilderImpl API.
All properties follow the usual quarkus.flow.http.client naming:
# Default client proxy (host/port)
quarkus.flow.http.client.proxy-host=proxy.mycorp.internal
quarkus.flow.http.client.proxy-port=3128
# Optional credentials
quarkus.flow.http.client.proxy-user=api-user
quarkus.flow.http.client.proxy-password=change-me
# Pipe-separated non-proxy hosts pattern (mirrors Java proxy syntax)
quarkus.flow.http.client.non-proxy-hosts=localhost|127.*|[::1]|*.svc.cluster.local
# Connect timeout (milliseconds) for proxy handshake
quarkus.flow.http.client.proxy-connect-timeout=5000
Named clients use the same pattern:
quarkus.flow.http.client.named.secureA.proxy-host=proxy.mycorp.internal
quarkus.flow.http.client.named.secureA.proxy-port=3128
If proxy-host is not set, the client falls back to standard JVM system properties
(http(s).proxyHost, etc.), consistent with the underlying Vert.x behavior.
9. Redirects, compression and chunk size
Additional tuning is available:
# Max redirects
quarkus.flow.http.client.max-redirects=5
# Follow redirects at the client level
quarkus.flow.http.client.follow-redirects=true
# Enable transparent decompression
quarkus.flow.http.client.enable-compression=true
# HTTP chunk size (bytes)
quarkus.flow.http.client.max-chunk-size=16384
All of these can be set per named client as well:
quarkus.flow.http.client.named.internal.max-redirects=2
quarkus.flow.http.client.named.internal.enable-compression=true
10. Multi-valued query parameters
If you rely on repeated query parameters (for example, ?tag=a&tag=b),
you can control how the underlying REST client encodes them:
# See MultiQueryParamMode enum in RESTEasy Reactive for supported values
quarkus.flow.http.client.multi-query-param-mode=multi
This maps to ClientBuilderImpl.multiQueryParamMode(…).
11. TLS, trust and host verification
For most use cases, you configure TLS using standard Quarkus SSL / REST client facilities.
Quarkus Flow exposes two booleans that directly map to ClientBuilderImpl.trustAll(boolean)
and verifyHost(boolean):
# Trust all certificates (including self-signed)
quarkus.flow.http.client.trust-all=true
# Disable hostname verification
quarkus.flow.http.client.verify-host=false
Only enable trust-all or disable verify-host in controlled environments
(for example, local development). In production these settings significantly reduce TLS security.
|
12. Putting it all together
Example: a typical setup using both default and named clients:
# Default client: used by most workflows
quarkus.flow.http.client.connect-timeout=5000
quarkus.flow.http.client.read-timeout=10000
quarkus.flow.http.client.user-agent=quarkus-flow/1.0
quarkus.flow.http.client.logging.scope=request-response
quarkus.flow.http.client.logging.body-limit=512
# Named client for a SaaS API
quarkus.flow.http.client.named.crm.connect-timeout=3000
quarkus.flow.http.client.named.crm.read-timeout=8000
quarkus.flow.http.client.named.crm.user-agent=MyCRMIntegrator/1.0
quarkus.flow.http.client.named.crm.static-headers=X-Env=prod
quarkus.flow.http.client.named.crm.http2=true
quarkus.flow.http.client.named.crm.enable-compression=true
# Route "customer-sync-flow" to the CRM client
quarkus.flow.http.client.workflow.customer-sync-flow.name=crm
# Override only a specific task in another flow
quarkus.flow.http.client.workflow.order-flow.task.pushOrderToCrm.name=crm
With this configuration:
-
most workflows use the default client
-
any HTTP / OpenAPI task in
customer-sync-flowuses thecrmclient -
within
order-flow, only thepushOrderToCrmtask usescrm; other tasks fall back to the default client
This lets you centralize all HTTP behavior (timeouts, logging, headers, proxy, TLS) per logical client, and route workflows and tasks declaratively without touching your Java or DSL code.
See also
-
Call HTTP and OpenAPI services — how to create HTTP/OpenAPI tasks in workflows.
-
Extension Configuration Reference — complete property list under
quarkus.flow.http.client.*. -
Using the REST Client Reactive — Quarkus REST client reactive guide.
-
QuarkusRestClientProperties — RESTEasy Reactive HTTP client properties.
-
SmallRye Config map support — details on map / complex configuration values.
-
Vert.x HttpClientOptions — low-level tuning options.