5.2 HTTP Listener Configuration, Path Matching & Query/URI Parameters
Key Takeaways
The HTTP Listener connector (http:listener) acts as an inbound event source that translates incoming HTTP/HTTPS requests into Mule Events containing HttpRequestAttributes, payload, and variables.
In global HTTP Listener configurations (http:listener-config), setting host='0.0.0.0' binds the server to all network interfaces, which is mandatory for CloudHub, Docker, and Kubernetes environments, while port 8081 (HTTP) and 8082 (HTTPS) are standard CloudHub routing ports.
Path matching rules follow strict precedence: exact path matches take priority over parameterized URI templates (/orders/{orderId}), which in turn take priority over wildcard paths (/api/*).
Inbound HTTP metadata is captured in HttpRequestAttributes and accessed via DataWeave expressions using dot notation (attributes.queryParams.status) or bracket notation (attributes.headers['Content-Type']), with bracket notation strictly required for hyphenated or special-character keys.
Dynamic HTTP response status codes and headers are managed through the listener's http:response and http:error-response blocks using expressions such as #[vars.httpStatus default 200] and #[vars.outboundHeaders default {}].
5.2 HTTP Listener Configuration, Path Matching & Query/URI Parameters
The HTTP Listener connector is the primary entry point for synchronous REST APIs, webhooks, and HTTP-based integrations built on Mule runtime engine 4. When an external client makes an HTTP request, the HTTP Listener receives the TCP packet, processes HTTP headers and query parameters, reads the request body, and constructs a structured Mule Event.
Mastering HTTP Listener configuration, path matching precedence, DataWeave parameter extraction, and dynamic response generation is essential for building resilient APIs and succeeding on the MuleSoft Certified Developer exam.
1. Global HTTP Listener Configuration (<http:listener-config>)
An HTTP Listener in a flow references a shared Global HTTP Listener Configuration element that defines network interface binding, port numbers, base paths, and TLS/HTTPS security.
<http:listener-config name="HTTP_Listener_config" basePath="/api/v1">
<http:listener-connection host="0.0.0.0" port="${http.port}" readTimeout="30000"/>
</http:listener-config>
Key Configuration Attributes:
name: Unique identifier referenced by flow-level<http:listener>components viaconfig-ref.basePath: Optional URL prefix appended to all endpoints using this configuration. For example, ifbasePath="/api/v1"and a flow specifiespath="/customers", the full URL path is/api/v1/customers.host:0.0.0.0(Recommended / Mandatory for CloudHub): Binds the listener to all available network interfaces. In CloudHub, containers, or multi-homed servers, listening on0.0.0.0allows the external load balancer to route traffic into the Mule worker.localhost/127.0.0.1: Binds only to the loopback interface, preventing external network access (suitable only for local internal debugging).
port: The TCP port on which the server listens. In CloudHub 1.0, HTTP services must listen on${http.port}(8081) and HTTPS services on${https.port}(8082).
HTTPS / TLS Configuration (<tls:context>)
To secure endpoints with TLS/HTTPS encryption, a <tls:context> is configured within the listener connection:
<http:listener-config name="HTTPS_Listener_config">
<http:listener-connection protocol="HTTPS" host="0.0.0.0" port="${https.port}">
<tls:context name="TLS_Context">
<tls:key-store
type="jks"
path="certificates/keystore.jks"
keyPassword="${secure::keystore.password}"
password="${secure::keystore.password}"
alias="mule-api" />
</tls:context>
</http:listener-connection>
</http:listener-config>
2. URL Path Matching Mechanics & Precedence Rules
A Mule application can host dozens of HTTP Listeners across multiple flows. When an inbound request arrives, the Mule HTTP runtime evaluates the request URI against all configured listener paths to determine which flow executes.
+-----------------------------------------------------------------------------------------+
| URL PATH STRUCTURE RESOLUTION |
| |
| http://0.0.0.0:8081 /api/v1 /customers/{customerId}/orders |
| |_________________| |_____| |____________________________| |
| Host & Port BasePath Flow Path |
| |
| Full Evaluated Request Path = [basePath] + [flowPath] |
+-----------------------------------------------------------------------------------------+
Path Syntax Types:
- Exact Path Matching:
path="/customers/active"— Matches only the exact literal path/customers/active. - Parameterized URI Templates:
path="/customers/{customerId}"orpath="/orders/{orderId}/items/{itemId}"— Matches dynamic path segments and extracts parameter values intoattributes.uriParams. - Wildcard Matching:
path="/api/*"orpath="/static/*"— Matches any URI path starting with the prefix. The asterisk matches zero or more trailing segments.
Path Collision & Precedence Hierarchy:
If an incoming request matches multiple configured listener paths, Mule runtime resolves the collision using a strict specificity hierarchy:
| Configured Flow Path | Inbound Request URI | Matching Result & Reason |
|---|---|---|
Flow A: path="/orders/summary"; Flow B: path="/orders/{orderId}" | GET /orders/summary | Flow A executes. Exact literal match (/orders/summary) takes precedence over the parameterized template (/orders/{orderId}). |
Flow A: path="/orders/summary"; Flow B: path="/orders/{orderId}" | GET /orders/99482 | Flow B executes. The request does not match the literal path, so it matches the parameterized template with attributes.uriParams.orderId = "99482". |
Flow A: path="/orders/*"; Flow B: path="/orders/{orderId}" | GET /orders/12345 | Flow B executes. Parameterized URI templates are more specific than generic wildcard (*) patterns. |
Flow A: path="/*"; Flow B: path="/api/*" | GET /api/users | Flow B executes. Longer prefix wildcard matches take precedence over root wildcards. |
3. Extracting Request Metadata in DataWeave 2.0
When an HTTP request is received, the listener instantiates an HttpRequestAttributes object inside message.attributes. This object is strictly immutable and exposes all HTTP metadata.
+-----------------------------------------------------------------------------------------+
| HTTP REQUEST ATTRIBUTES STRUCTURE |
| |
| attributes |
| ├── queryParams: { status: "ACTIVE", region: "US-EAST", 'start-date': "2026-01-01" } |
| ├── uriParams: { customerId: "CUST-8821", orderId: "ORD-109" } |
| ├── headers: { 'content-type': "application/json", 'x-correlation-id': "abc-123"}|
| ├── method: "POST" |
| ├── requestPath: "/api/v1/customers/CUST-8821/orders/ORD-109" |
| ├── queryString: "status=ACTIVE®ion=US-EAST&start-date=2026-01-01" |
| └── listenerPath:"/api/v1/customers/{customerId}/orders/{orderId}" |
+-----------------------------------------------------------------------------------------+
Accessing Query Parameters:
Query parameters are key-value pairs passed in the URL query string (?key1=val1&key2=val2):
- Standard Keys:
attributes.queryParams.statusorattributes.queryParams.region - Hyphenated / Special Character Keys:
attributes.queryParams['start-date']orattributes.queryParams['filter[category]'] - Safe Navigation / Defaulting:
attributes.queryParams.limit default 25
Accessing URI (Path) Parameters:
URI parameters are dynamic placeholders declared in the listener path (path="/customers/{customerId}/orders/{orderId}"):
attributes.uriParams.customerIdattributes.uriParams.orderIdattributes.uriParams['customerId']
Accessing Request Headers:
HTTP headers contain metadata such as tokens, content types, and correlation IDs. Note that HTTP header names are case-insensitive in the HTTP protocol, but Mule normalizes them to lowercase internally:
- Dot Notation (Standard keys without hyphens):
attributes.headers.host - Bracket Notation (Hyphenated keys - MANDATORY):
attributes.headers['Content-Type'],attributes.headers['x-correlation-id'],attributes.headers['Authorization']
Important
Dot Notation Syntax Error with Hyphens
Writing attributes.headers.X-Correlation-ID in DataWeave evaluates as attributes.headers.X minus Correlation minus ID (subtraction operator), causing a runtime evaluation failure. Always use bracket notation attributes.headers['X-Correlation-ID'] for hyphenated headers and query parameters.
4. Configuring Response Status Codes, Headers & Error Responses
The <http:listener> component controls the HTTP response returned to the calling client through two child elements: <http:response> (for successful flow executions) and <http:error-response> (when an unhandled exception or error occurs).
<flow name="processOrderFlow">
<http:listener config-ref="HTTP_Listener_config" path="/orders">
<!-- Success Response Configuration -->
<http:response statusCode="#[vars.httpStatus default 200]" reasonPhrase="#[vars.httpReasonPhrase default 'OK']">
<http:body><![CDATA[#[payload]]]></http:body>
<http:headers><![CDATA[#[vars.outboundHeaders default {
"Content-Type": "application/json",
"X-Transaction-ID": vars.transactionId
}]]]></http:headers>
</http:response>
<!-- Error Response Configuration -->
<http:error-response statusCode="#[vars.httpStatus default 500]" reasonPhrase="#[vars.httpReasonPhrase default 'Server Error']">
<http:body><![CDATA[%dw 2.0
output application/json
---
{
"error": {
"code": vars.httpStatus default 500,
"message": error.description default "Internal execution error",
"type": error.errorType.identifier default "UNKNOWN",
"timestamp": now()
}
}]]></http:body>
<http:headers><![CDATA[#[vars.outboundHeaders default {}]]]></http:headers>
</http:error-response>
</http:listener>
<!-- Flow Processors -->
<set-variable variableName="transactionId" value="#[uuid()]"/>
<ee:transform>
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
{"orderId": "ORD-9912", "status": "CREATED"}]]></ee:set-payload>
</ee:message>
<ee:variables>
<ee:set-variable variableName="httpStatus"><![CDATA[201]]></ee:set-variable>
</ee:variables>
</ee:transform>
</flow>
Response Evaluation Mechanics:
- Default Status Codes:
- Success: If
statusCodeis omitted or evaluates to null, the listener defaults to200 OK(or204 No Contentif payload is null). - Error: If
statusCodeis omitted or evaluates to null in<http:error-response>, the listener defaults to500 Internal Server Error.
- Success: If
- Dynamic Status Code Assignment: By using
#[vars.httpStatus default 200], any processor inside the flow or error handler can setvars.httpStatus(e.g.,201for created,202for accepted,404for not found,409for conflict) to dynamically control the HTTP status returned to the client. - Custom Response Headers: The
<http:headers>element accepts a DataWeave map expression, allowing developers to inject custom tracking headers, CORS headers (Access-Control-Allow-Origin), or rate-limiting metadata.
5. Exam Watch: HTTP Listener & Parameter Scenarios
Important
Host Binding on CloudHub (0.0.0.0 vs localhost)
An extremely common exam question asks why an application deployed to CloudHub returns connection timeouts or 502 Bad Gateway errors despite deploying successfully. The cause is almost always configuring host="localhost" in the HTTP Listener. CloudHub requires host="0.0.0.0" so the load balancer can route external traffic into the worker container.
Warning
Inbound Attributes Are Immutable and Replaced
Inbound HttpRequestAttributes exist when the flow starts. However, if the flow invokes an outbound <http:request> or <db:select>, the message attributes are completely replaced with HttpResponseAttributes or DatabaseAttributes. To access original query or URI parameters later in the flow, save them to vars before invoking downstream connectors.
Tip
Dynamic Error Status Handling
In an on-error-continue block, the flow completes successfully from the perspective of the HTTP Listener, returning the <http:response> (default 200) unless vars.httpStatus is explicitly assigned a 4xx/5xx status code.
A developer writes a DataWeave expression inside a Logger component to inspect an inbound custom tracing header named X-Client-Trace-Id. Which expression correctly extracts the header value from the Mule Event?
headers.'X-Client-Trace-Id'
attributes.headers['X-Client-Trace-Id']
attributes.headers.X-Client-Trace-Id
message.inboundProperties['X-Client-Trace-Id']
A Mule application has two flows with HTTP Listeners sharing the same host and port. Flow 1 defines path="/customers/vip". Flow 2 defines path="/customers/{customerId}". A client submits an HTTP GET request to /customers/vip. How does the Mule runtime handle this request?
Both flows execute concurrently, and their payloads are merged into an array.
The HTTP Listener throws a routing collision error and returns an HTTP 500 status code.
Flow 2 executes because parameterized URI templates take precedence over literal string paths.
Flow 1 executes because exact path matches take precedence over parameterized URI templates.
An integration developer must configure an HTTP Listener to return an HTTP status code of 201 Created when a record is inserted, but default to 200 OK for other operations, and return 400 Bad Request if validation fails inside an error handler. How should the HTTP Listener and flows be configured?
Configure <http:response statusCode="#[vars.httpStatus default 200]"> on the listener, and assign <set-variable variableName="httpStatus" value="201"/> in the creation flow and 400 in the error handler.
Use MEL expression #[message.outboundProperty('http.status') = 201] in a Message Properties transformer.
Hardcode statusCode="201" in the <http:response> and configure an API Gateway policy to dynamically alter the status code to 400 upon error.
Set the <http:response> statusCode to #[payload.statusCode] and ensure all flow processors output a JSON object containing a statusCode field.
A Mule 4 application deployed to CloudHub fails to receive any inbound traffic, and external clients receive connection timeout errors. The application logs indicate the application started successfully. Inspection of the HTTP Listener configuration reveals host="localhost" and port="8081". What change is required to resolve the issue?
Enable cross-origin resource sharing (CORS) in the HTTP Listener advanced configuration tab.
Change the base path from / to /api/* to allow wildcard routing.
Change the host from localhost to 0.0.0.0 to allow the CloudHub load balancer to bind to the worker interface.
Change the port to 443 and add a self-signed SSL certificate to the keystore.
Sections you finish are checked off in the contents.